我什么时候应该调用getBeansFromFiles(),以便BeanFactory的创建和bean的自动装配都能工作?

时间:2018-03-08 21:51:33

标签: java spring spring-mvc

所以我使用Spring生成随机故事,我在控制器的第73行得到一个NullPointerException,我调用ApplicationContext在获取bean的函数中创建BeanFactory(MadLib和PartOfSpeech类) )来自文本文件。在添加该函数之前,上下文工作正常。怎么了?

编辑:我知道NullPointerException是什么。我不知道为什么会发生这种情况。此外,它在我注释掉构造函数时有效。我认为问题可能是我试图在它存在之前调用上下文?

编辑2:我尝试将对getBeansFromFiles()的调用移动到第一个GetMapping(链接)。这消除了NullPointerException,可能是因为Controller bean已经初始化,因此存在上下文。但是当MadLibs被添加到列表中时,bean没有被创建或者至少没有自动装配。有没有一个地方可以把这个电话放在哪里都可以工作?我是否需要实现一个能够在合适的时间进行此调用的界面?

package controllers;

import...


@Controller
@RequestMapping(value = "/madLib")
public class MadLibController {
    @Autowired
    ApplicationContext context;

    public MadLibController(){
        getBeansFromFiles();
    }

    public PartOfSpeech pos(String path){
        String input;
        try {
            input = utility.Util.readFile(path);
        } catch (IOException e) {
            e.printStackTrace();
            input = "v";
        }
        return new PartOfSpeech(input);
    }

    public MadLib ml(String path){
        String input;
        System.out.println(new File("").getAbsolutePath());
        try {
            input = utility.Util.readFile(path);
        } catch (IOException e) {
            e.printStackTrace();
            input = "v#V#v";
        }
        return new MadLib(input);
    }

    public void getBeansFromFiles() {
        AutowireCapableBeanFactory beanFactory = context.getAutowireCapableBeanFactory();
        File folder = new File("../../txt/ml");
        File[] listOfFiles = folder.listFiles();
        for (File file : listOfFiles){
            System.out.println("File path: " + file.getPath());
            MadLib ml = ml(file.getPath());
            String beanName = ml.getId();
            beanFactory.autowireBean(ml);
            beanFactory.initializeBean(ml, beanName);
            ((MadLibList)context.getBean("madLibList")).getList().add(ml);
        }
        folder = new File("../../txt/pos");
        listOfFiles = folder.listFiles();
        for (File file : listOfFiles){
            System.out.println("File path: " + file.getPath());
            PartOfSpeech pos = pos(file.getPath());
            String beanName = pos.getId();
            beanFactory.autowireBean(pos);
            beanFactory.initializeBean(pos, beanName);
        }
    }

    /*@Bean("verb")
    public PartOfSpeech verb(){
        return pos("verb");
    }

    @Bean("hansel2")
    public MadLib hansel2(){
        return ml("hansel");
    }

    @Bean("lunch")
    public MadLib lunch(){
        return ml("lunch");
    }*/



    @GetMapping
    public String links(Model model){
        MadLibList list = (MadLibList)context.getBean("madLibList");
        //list.getList().add(hansel2());
        //list.getList().add(lunch());
        model.addAttribute("madLibList", list);
        return "madLibLinks";
    }

    @GetMapping("/{name}")
    public String prompts(HttpServletRequest req, HttpServletResponse res, 
            Model model, @PathVariable("name") String name, 
            @RequestParam(value = "random", defaultValue = "false") String random){
        MadLib madLib = (MadLib)context.getBean(name);
        madLib.setAnswers(new ArrayList<String>(madLib.getPrompts().size()));
        System.out.println("Answers: " + madLib.getAnswers());
        if (random.equals("true")){
            System.out.println("Prompts: " + madLib.getPrompts());
            for (int i=0; i<madLib.getPrompts().size(); i++){
                try {
                    String posBean = utility.Util.camelCase(madLib.getPrompts().get(i));
                    PartOfSpeech pos = (PartOfSpeech)context.getBean(posBean);
                    String word = pos.getWord();
                    System.out.println(word);
                    madLib.getAnswers().add(word);
                } catch (Exception e) {
                    System.out.println("exception in randomizing answers for " + madLib.getPrompts().get(i));
                    System.out.println(e);
                    madLib.getAnswers().add("");
                }
            }
        }
        model.addAttribute("default", "");
        model.addAttribute("madLib", madLib);
        return "madLibPrompts";
    }

    @PostMapping(value = "/result")
    public String result(Model model, @ModelAttribute("madLib") MadLib madLib, BindingResult result){
        System.out.println(madLib.getAnswers().get(0));
        //model.addAttribute(madLib);
        return "madLibResult";
    }



}

1 个答案:

答案 0 :(得分:0)

实现BeanDefinitionRegistryPostProcessor并使用beanFactory而不是context

package controllers;

import...

@Controller
@RequestMapping(value = "/madLib")
public class MadLibController implements BeanDefinitionRegistryPostProcessor {
    @Autowired
    ApplicationContext context;

    ConfigurableListableBeanFactory beanFactory;

    private BeanDefinitionRegistry registry;

    public PartOfSpeech pos(String path){
        String input;
        try {
            input = utility.Util.readFile(path);
        } catch (IOException e) {
            e.printStackTrace();
            input = "v";
        }
        return new PartOfSpeech(input);
    }

    public MadLib ml(String path){
        String input;
        System.out.println(new File("").getAbsolutePath());
        try {
            input = utility.Util.readFile(path);
        } catch (IOException e) {
            e.printStackTrace();
            input = "v#V#v";
        }
        return new MadLib(input);
    }

    public void getBeansFromFiles() {
        File folder = new File("../../txt/ml");
        File[] listOfFiles = folder.listFiles();
        for (File file : listOfFiles){
            System.out.println("File path: " + file.getPath());
            MadLib ml = ml(file.getPath());
            String beanName = ml.getId();
            beanFactory.registerSingleton(beanName, ml);
            ((MadLib)beanFactory.getBean(beanName)).setId(ml.getId());
            ((MadLib)beanFactory.getBean(beanName)).setTitle(ml.getTitle());
            ((MadLib)beanFactory.getBean(beanName)).setAnswers(ml.getAnswers());
            ((MadLib)beanFactory.getBean(beanName)).setPrompts(ml.getPrompts());
            ((MadLib)beanFactory.getBean(beanName)).setStrings(ml.getStrings());
            ((MadLibList)beanFactory.getBean("madLibList")).getList().add(ml);
        }
        folder = new File("../../txt/pos");
        listOfFiles = folder.listFiles();
        for (File file : listOfFiles){
            System.out.println("File path: " + file.getPath());
            PartOfSpeech pos = pos(file.getPath());
            String beanName = pos.getId();
            beanFactory.registerSingleton(beanName, pos);
            ((PartOfSpeech)beanFactory.getBean(beanName)).setName(pos.getName());
            ((PartOfSpeech)beanFactory.getBean(beanName)).setWords(pos.getWords());
        }
    }


    @GetMapping
    public String links(Model model){
        MadLibList list = (MadLibList)beanFactory.getBean("madLibList");
        model.addAttribute("madLibList", list);
        return "madLibLinks";
    }

    @GetMapping("/{name}")
    public String prompts(HttpServletRequest req, HttpServletResponse res, 
            Model model, @PathVariable("name") String name, 
            @RequestParam(value = "random", defaultValue = "false") String random){
        MadLib madLib = (MadLib)beanFactory.getBean(name);
        //System.out.println(madLib);
        madLib.setAnswers(new ArrayList<String>(madLib.getPrompts().size()));
        System.out.println("Answers: " + madLib.getAnswers());
        if (random.equals("true")){
            System.out.println("Prompts: " + madLib.getPrompts());
            for (int i=0; i<madLib.getPrompts().size(); i++){
                try {
                    String posBean = utility.Util.camelCase(madLib.getPrompts().get(i));
                    PartOfSpeech pos = (PartOfSpeech)beanFactory.getBean(posBean);
                    String word = pos.getWord();
                    System.out.println(word);
                    madLib.getAnswers().add(word);
                } catch (Exception e) {
                    System.out.println("exception in randomizing answers for " + madLib.getPrompts().get(i));
                    System.out.println(e);
                    e.printStackTrace();
                    madLib.getAnswers().add("");
                }
            }
        }
        model.addAttribute("default", "");
        model.addAttribute("madLib", madLib);
        return "madLibPrompts";
    }

    @PostMapping(value = "/result")
    public String result(Model model, @ModelAttribute("madLib") MadLib madLib, BindingResult result){
        System.out.println(madLib.getAnswers().get(0));
        //model.addAttribute(madLib);
        return "madLibResult";
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0) throws BeansException {
        this.beanFactory = arg0;
        getBeansFromFiles();
    }

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry arg0) throws BeansException {
        this.registry = arg0;
    }



}