[JavaEE]SpringBoot使用自动注入@Autowired失败

    最近在搞抄袭,抄哪家就不说了,反正人家开源了源码,然后就涉及到了JavaEE的开发。想起了读研的时候开发的教学管理系统,那会还是用的框架还是SSH,然后第一份工作中也涉及了部分云端开发,用的框架是SSM,没想到干了一年又需要整这个,看来搞Android没前途呀,哈哈哈哈,扯远了~

    先说遇到的问题:在Servlet里使用了自动注入失败,报空指针异常。这个问题其实拆分下来是两个问题,问题一:Servlet如何使用Spring的自动注入;问题二:static关键字修饰的自动注入对象失败。

    先说问题一:网上百度搜了一下,基本上解释都是千篇一律,说是注解@ComponentScan所注解的Application没有在根目录,导致搜不到对应的类,这个吧是导致注入失败的原因之一,但是不是我遇到的问题,只能说是我这个搜的问题没有描述清楚。我遇到的问题的根本是Servlet使用了@Autowired失败,网上大神的说法是,Servlet和Spring不是统一由Spring管理的,所以在Servlet里不能直接使用Spring的注解,解决办法如下:

@WebServlet("/sevlet/test")
public class TestServlet extends HttpServlet {

    @Override
    public void init() throws ServletException {
        WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()).getAutowireCapableBeanFactory().autowireBean(this);
        super.init();
        ServletContext application = this.getServletContext();
        // 解决servlet用@Autowired自动注入service失败的问题
        SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, application);
        if (testController == null) {
            System.out.println("========== 注入失败 ==========");
        } else {
            System.out.println("========== 注入成功 ==========");
            TestControllerUtil controllerUtil = new TestControllerUtil();
            controllerUtil.setTestController(testController);
        }
    }

    @Autowired
    private TestController testController;

    public TestServlet() {
        super(getSkill());
    }

    private static Skill getSkill() {
        Skill skill = Skills.custom()
                .addRequestHandlers(new PhoneCallHandler())
                .withSkillId("adbcdefg")
                .build();
        return skill;
    }
}

    其实就是在init()的时候加入了一句话就可以在servlet里使用自动注入了。第一个问题就算是解决了。

    接下来是第二个问题:static关键字修饰的自动注入对象失败。从上面的代码里可以看到,我在注入成功了之后还调用了一个Util然后把testController通过set方法传进去。其实最开始的时候是这样写的:

    @Autowired
    private static PhoneController phoneController;

    然后就注入失败,报空指针了。这个时候就不得不找原因了:原因是自动注入实际上是由Spring自动new了一个对象,而static修饰的对象是在程序一开始的时候就初始化了,也就是static的初始化比较早,这个解决方法就是自己写一个工具类,然后通过set方法把自动注入的对象传进去,代码如下:

public class TestControllerUtil {

    private static TestController testController;

    public TestController getContactController() {
        return testController;
    }

    public void setTestController(TestController testController) {
        TestControllerUtil.testController = testController;
    }

    public static ContactEntity searchContact(String phoneNumber, String name) {
        ContactEntity contactEntity = testController.searchContact(phoneNumber, name);
        return contactEntity;
    }

    public static String searchPhoneNumberByUserId(String userId) {
        String phoneNumber = testController.getUserPhoneNumber(userId);
        return phoneNumber;
    }
}

    注意set方法不是static的。至此,解决了这两个问题。

    最后不得不说,Spring还是强大啊,IOC和AOP,不过我太久没碰了,早就忘光了,哎,我还是太菜。

发布了61 篇原创文章 · 获赞 2 · 访问量 8717

猜你喜欢

转载自blog.csdn.net/woaily1346/article/details/93196544
今日推荐