npe

z0qdvdin  于 2021-07-23  发布在  Java
关注(0)|答案(1)|浏览(290)

这个问题在这里已经有答案了

为什么我的spring@autowired字段为空(22个答案)
什么是nullpointerexception,如何修复它(12个答案)
两个月前关门了。
我在我的springboot项目中有下面的代码,该项目在前面提到的特定行中抛出npe。

Exception in thread "main" java.lang.NullPointerException
  at com.temp.controller.Controller.triggerJob(Controller.java:15)
  at com.temp.Application.main(Application.java:19)

应用程序.java

@Configuration
@SpringBootApplication
@ImportResource({"classpath:applicationContext.xml"})
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);

        Controller controller = new Controller();
        controller.triggerJob();
    }
}

控制器.java

@Controller
public class Controller {
    @Autowired
    private Service Service;

    public void triggerJob() {
        Service.selectRecords();
    }
}

service.selectrecords();是npe被抛出的地方
服务.java

public interface Service {
    List<VO> selectRecords();
}

serviceimpl.java文件

@Service
public class ServiceImpl implements Service {
    @Autowired
    private Dao dao;

    @Override
    public List<VO> selectRecords() {
        return dao.selectRecords();
    }
}

应用程序上下文.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
                            http://www.springframework.org/schema/jdbc
                            http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
                            http://www.springframework.org/schema/util 
                            http://www.springframework.org/schema/util/spring-util-3.2.xsd
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context-3.2.xsd">

    <util:properties id="configProperties"
        location="file:${app.config.home}/config/config-${spring.profiles.active}.properties" />

    <context:property-placeholder
        location="file:${app.config.home}/config/config-${spring.profiles.active}.properties" />

    <bean id="crypt" class="com.temp.util.MyUtil">
        <property name="userId" value="${username}"></property>
        <property name="password" value="${password}"></property>
        <property name="key" value="123456789012345678901234"></property>
    </bean>

    <bean id="datasource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${driver}" />
        <property name="url" value="${connection}" />
        <property name="username" value="#{crypt.userId}" />
        <property name="password" value="#{crypt.password}" />
    </bean>

    <bean id="namedJdbcTemplate"
        class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
        <constructor-arg ref="datasource" />
    </bean>
</beans>

我有一个类似的项目这样,并比较了两者的配置,他们是相同的,除了2件事。
springbootstarter版本对于这个项目是2.4.2,对于另一个项目是1.5.3。
这个项目的java版本是11,另一个项目是1.8。
不知道我哪里出错了。
我错过什么了吗?请帮忙。

nhjlsmyf

nhjlsmyf1#

您正在创建新示例 Controller controller = new Controller(); 而此示例不在spring上下文中。因此,服务的注入(自动连线)示例为空。 @Autowired 仅当示例存在于spring上下文中时才起作用。
最好的方法是保持控制器的可测试性,即通过构造函数注入:

@Configuration
@SpringBootApplication
@ImportResource({"classpath:applicationContext.xml"})
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);

        Controller controller = new Controller(new ServiceImpl(new DaoImpl()));
        controller.triggerJob();
    }
}

通过构造函数注入示例:

@Controller
    public class Controller {

        private final Service Service;

        public Controller(final Service Service) {
           this.service = service;
        }

        public void triggerJob() {
            Service.selectRecords();
        }
    }

并通过构造函数注入dao依赖关系:

@Service
public class ServiceImpl implements Service {

    private final Dao dao;

    public ServiceImpl(final Dao dao) {
       this.dao = dao;
    }

    @Override
    public List<VO> selectRecords() {
        return dao.selectRecords();
    }
}

对于4.3以上的Spring版本, @Autowired 可以从构造函数的顶部省略,spring自动扫描注入并通过构造函数注入依赖项。对于4.3以下的spring版本,添加 @Autowired 在施工人员之上,即:

@Controller
public class Controller {

    private final Service Service;

    @Autowired
    public Controller(final Service Service) {
       this.service = service;
    }

    public void triggerJob() {
        Service.selectRecords();
    }
}

相关问题