java 自动装配类为空

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28937783/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 14:25:49  来源:igfitidea点击:

Autowired class is null

javaspringdaomybatis

提问by hina10531

SUMMARY

概括

I'm building a spring-mvc web application and trying to use Mybatis and DAO for data access.

我正在构建一个 spring-mvc Web 应用程序并尝试使用 Mybatis 和 DAO 进行数据访问。

I configured Mybatis successfully and I was able to fetch expected data from Mysql server.

我成功配置了 Mybatis,并且能够从 Mysql 服务器获取预期的数据。

But a problem occured when I tried to use DAO with Mybatis.

但是当我尝试在Mybatis中使用DAO时出现了一个问题。

ERROR

错误

As you could see below, it's a NullPointerException.

正如你在下面看到的,它是一个NullPointerException.

INFO : com.*****.web.controller.ExampleController - testDaoSelect action has been executed. No parameter has been taken.
INFO : com.*****.web.service.exampleService - Executed or not??
09, March, 2015 5:07:28 PM org.apache.catalina.core.StandardWrapperValve invoke
Fatal: Servlet.service() for servlet [appServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException
    at com.*****.web.service.exampleService.sampleList(exampleService.java:29)
    at com.*****.web.controller.ExampleController.testDaoSelect(ExampleController.java:188)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:644)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1086)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:659)
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1558)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1515)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)


REPRODUCING ERORR

再现错误

Starting with AJAX call.

从 AJAX 调用开始。

    $('#DaoSelectTest').click(function(e) {
    $.ajax({
        type: "POST",
        url: "/testDaoSelect.fst",
        data: {},
        success: function (result) {
            console.log(result);

            var html = "Querying was successful. Check out console logs. <br/>";
            html += "Done with the test. <a href='/daoSample.fst'>Click here</a> ";
            html += "And proceed to the next.";

            $('#sampleTable').html(html);
        },
        error: function (result) {
            // error...
        }
    });
});

And next, the action is executed..

接下来,执行动作..

@Controller
public class ExampleController {

    // Mybatis direct
    @Autowired
    private SqlSession sqlSession;

    // Dao  
    @Autowired
    private exampleService exService;
.
.
.
.
.


@RequestMapping("/testDaoSelect")
        @ResponseBody
        public List<HashMap<String, Object>> testDaoSelect(HttpServletRequest request, HttpServletResponse response) {
            logger.info("testDaoSelect action has been executed. No parameter has been taken.");

            List<HashMap<String, Object>> result = exService.sampleList();

            logger.info("result size is... " + result.size());

            return result;
        }

Calling textDaoSelectis alright, and what's next is Service class.

调用没问题textDaoSelect,接下来是Service类。

@Service
@Transactional
public class exampleService {

    private Log logger = LogFactory.getLog(this.getClass());

    @Autowired
    private exampleDao exDao;

    @Transactional(readOnly = true)
    public List<HashMap<String, Object>> sampleList() {
        logger.info("Executed or not??");

        return exDao.sampleList();
    }
}

BOOM~! HERE

砰~!这里

exDao is null here, NullPointExceptionoccurs here. It's not correctly wired. Why?? And What should I do??

exDao 在这里为空,NullPointException发生在这里。它没有正确接线。为什么??我该怎么办??

My exampleDao

我的榜样道

public interface exampleDao {
    public List<HashMap<String, Object>> sampleList();
}

**My exampleDaoImplement

**我的例子DaoImplement

public class exampleDaoImplement extends SqlSessionDaoSupport implements exampleDao {

    private static final Logger logger = LoggerFactory.getLogger(exampleDaoImplement.class);    

    public List<HashMap<String, Object>> sampleList() {
        // TODO Auto-generated method stub

        logger.info("I've reached impl class....");
        return getSqlSession().selectList("Example.selectTest");

    }
}

MY ROOT CONTEXT

我的根背景

( Forget about ******anyway... )

(算了******……)

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

    <!-- Root Context: defines shared resources visible to all other web components -->

    <bean id="dataSource" class="org.apache.ibatis.datasource.pooled.PooledDataSource">
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://*******:3306/*****_web"/>
        <property name="username" value="root"/>
        <property name="password" value="*******"/>
    </bean>

    <bean id ="sqlSessionFactory" class= "org.mybatis.spring.SqlSessionFactoryBean" >
        <property name ="dataSource" ref= "dataSource"></property >
        <property name="configLocation" value="classpath:mybatis/mybatis-config.xml" />
    </bean >

    <bean id ="transactionManager"
        class= "org.springframework.jdbc.datasource.DataSourceTransactionManager" >
        <property name ="dataSource" ref= "dataSource"></property >
    </bean >

    <bean id ="sqlSession"
        class= "org.mybatis.spring.SqlSessionTemplate" >
        <constructor-arg ref= "sqlSessionFactory"></constructor-arg >
    </bean >

    <bean id ="exService" class= "com.*****.web.service.exampleService" ></bean >

</beans>

My servlet-context

我的 servlet 上下文

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

    <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

    <!-- Enables the Spring MVC @Controller programming model -->
    <annotation-driven />

    <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
    <resources mapping="/resources/**" location="/resources/" />

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>

    <context:component-scan base-package="com.******.web.controller" />

</beans:beans>

I've googled on this for like a half a day, and got some hints but no exact solutions. What seems to be the matter??

我已经用谷歌搜索了半天,得到了一些提示,但没有确切的解决方案。好像是怎么回事??



ADDED

添加

While googling, I got this hint and configured accordingly.

在谷歌搜索时,我得到了这个提示并进行了相应的配置。

<bean id ="exDao" class= "com.*****.web.dao.implement.exampleDaoImplement" >
    <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean >

( without defining property, It throws error while starting up the server, saying that property sqlSessionFactoryor SqlSessionTemplateis required. )

(没有定义属性,它在启动服务器时抛出错误,说该属性sqlSessionFactory或是SqlSessionTemplate必需的。)

But it doesn't work... even with this configuration, there's still the nullpoint error.

但它不起作用......即使使用这种配置,仍然存在空点错误。

回答by Grégtheitroade C

First idea: in servlet-context.xml, you have written:

第一个想法:在servlet-context.xml 中,你写了:

<context:component-scan base-package="com.******.web.controller" />

<context:component-scan base-package="com.******.web.controller" />

This means that Spring will look for your annotated classes (like @Serviceand others) onlyinside this folder. Did you, by any chance, put your DAO outside of the "com.******.web.controller" folder? This would explain why it remains null.

这意味着 Spring 将在此文件夹中查找您的带注释的类(如@Service和其他类)。你有没有把你的 DAO 放在“com.******.web.controller”文件夹之外?这将解释为什么它仍然存在。null

A simple test is to use "com.******" to make sure that every folders are scanned.

一个简单的测试是使用“com.******”来确保扫描每个文件夹。

Second idea: if you want that Spring instanciates your DAO class, you have to add the @Repositoryannotation in your concrete implementation of the DAO interface.

第二个想法:如果你想让 Spring 实例化你的 DAO 类,你必须@Repository在 DAO 接口的具体实现中添加注释。

Third idea: you should not use XML-configuration and an annotation for the same class. In your example, you don't need to use <bean id ="exService" class= "com.*****.web.service.exampleService"></bean >if you use @Servicein the exampleServiceclass and your <component-scan>covers the directory where the service is.

第三个想法:你不应该对同一个类使用 XML 配置和注释。在您的示例中,<bean id ="exService" class= "com.*****.web.service.exampleService"></bean >如果您@ServiceexampleService类中使用并且您<component-scan>覆盖了服务所在的目录,则不需要使用。

Final note: You write in the comments that using @Service("exService")solved your problem. This is due to the fact that, if you don't specify the name of your components, Spring looks up for any existing bean with the given type(and not its name). So, it injected the bean you declared in XML, which had a nullDAO.

最后说明:您在评论中写道,使用@Service("exService")解决了您的问题。这是因为,如果您不指定组件的名称,Spring 将查找具有给定类型(而不是其名称)的任何现有 bean 。所以,它注入了你在 XML 中声明的 bean,它有一个nullDAO。

To avoid this kind of problems, you should always explicitly name your beans after the name of the variable where you use it, here @Service("exService")toggles the "bind by name" behaviour, which makes your code works as expected:

为避免此类问题,您应该始终在使用它的变量名称之后明确命名您的 bean,这里@Service("exService")切换“按名称绑定”行为,这使您的代码按预期工作:

// This works because the name of the variable
// matches the @Service("exService") annotation
@Autowired
private ExampleService exService;

Thanks go to @RohitJain for this last note.

感谢@RohitJain 提供最后一个注释。



Unrelated to your problem, Java classes and interfaces should always be written with an uppercase letter (e.g. "ExampleDao", "ExampleDaoImplement" and "ExampleService").

与您的问题无关,Java 类和接口应始终使用大写字母编写(例如“ExampleDao”、“ExampleDaoImplement”和“ExampleService”)。

回答by EpicPandaForce

This is a really wild guess, but I think you should rename exampleDaoImplementto exampleDaoImplwith a refactor rename.

这是一个非常疯狂的猜测,但我认为您应该使用重构重命名exampleDaoImplementexampleDaoImpl重命名为。

回答by Linyun Liu

My implementation uses pure XML spring config and everything is fine since the web-app is able to boot up normally without any errors.

我的实现使用纯 XML spring 配置,一切都很好,因为网络应用程序能够正常启动而没有任何错误。

But I still got null exception for a DAO instance autowired by name and I solved it by adding a getter and one setter for it.

但是对于按名称自动装配的 DAO 实例,我仍然遇到空异常,我通过为它添加了一个 getter 和一个 setter 来解决它。