【问题标题】:@autowiring is not getting injected@autowireing 没有被注入
【发布时间】:2015-09-08 10:25:25
【问题描述】:

我有两个服务类和一个存储库类。当我尝试将一个服务 bean 自动装配到另一个服务 bean 时,会注入一个 bean。但是当我尝试调用该方法时,它会显示NullPointerException。请帮帮我。在过去的 3 天里,我一直坚持这一点。

我的第一个服务班:

@Service
public class MetaData implements MetaDataService {


    private AffiliateRepository util;

    @Autowired
    public MetaData(AffiliateRepository util) {
        this.util = util;// I can see bean getting injected
    }

    public boolean findByEmail() {

        // some logic
    }

}

我的第二个服务等级:

@Service
public class ResetPasswordForm implements ResetPasswordFormService {

    public ResetPasswordForm() {

    }

           private MetaDataService md;

    @Autowired
    public ResetPasswordForm(MetaDataService md) {
        this.md = md; // when iam debugging I could see bean got injected at this point.
    }

    public void advancedValidation(Map<String, String> errors) {

        else if (id.contains("@") && md.findByEmail())// when iam calling method present in class using md it is showing md is null {
                                }
    }
}

我的存储库类:

@Repository
public class JpaAffiliate implements AffiliateRepository, Serializable {
    private   EntityManagerFactory emf;

    @PersistenceUnit(unitName="resetpwd-unit")
    public void setEntityManagerFactory(EntityManagerFactory emf) {
        this.emf = emf;
    }

    @SuppressWarnings("unchecked")
    public List<Affiliate> findAffiliate(String value) {
        // calls to database
    }
}

我已经尝试了所有方法(例如,&lt;context:component-scan base-package&gt; 指向我的基本包)。可能是什么问题?

下面是我的完整堆栈跟踪

ResetPasswordForm.java:134) [classes:]
    at (ResetPasswordForm.java:119) [classes:]
    at ...resetpwd.web.Page.getPage(Page.java:38) [classes:]
    at ....web.ResetPasswordController.addContact(ResetPasswordController.java:52) [classes:]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_55]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_55]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_55]
    at java.lang.reflect.Method.invoke(Method.java:606) [rt.jar:1.7.0_55]
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219) [spring-web-3.2.6.RELEASE.jar:3.2.6.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) [spring-web-3.2.6.RELEASE.jar:3.2.6.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) [spring-webmvc-3.2.6.RELEASE.jar:3.2.6.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745) [spring-webmvc-3.2.6.RELEASE.jar:3.2.6.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686) [spring-webmvc-3.2.6.RELEASE.jar:3.2.6.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) [spring-webmvc-3.2.6.RELEASE.jar:3.2.6.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925) [spring-webmvc-3.2.6.RELEASE.jar:3.2.6.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856) [spring-webmvc-3.2.6.RELEASE.jar:3.2.6.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936) [spring-webmvc-3.2.6.RELEASE.jar:3.2.6.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:838) [spring-webmvc-3.2.6.RELEASE.jar:3.2.6.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:754) [jboss-servlet-api_3.0_spec-1.0.2.Final-redhat-1.jar:1.0.2.Final-redhat-1]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812) [spring-webmvc-3.2.6.RELEASE.jar:3.2.6.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.2.Final-redhat-1.jar:1.0.2.Final-redhat-1]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101) [spring-web-3.2.6.RELEASE.jar:3.2.6.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) [spring-web-3.2.6.RELEASE.jar:3.2.6.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-3.2.6.RELEASE.jar:3.2.6.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) [spring-web-3.2.6.RELEASE.jar:3.2.6.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-3.2.6.RELEASE.jar:3.2.6.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
    at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.3.0.Final-redhat-14.jar:7.3.0.Final-redhat-14]
    at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.3.0.Final-redhat-14.jar:7.3.0.Final-redhat-14]
    at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169) [jboss-as-web-7.3.0.Final-redhat-14.jar:7.3.0.Final-redhat-14]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:145) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:336) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
    at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:488) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
    at org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.java:420) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:920) [jbossweb-7.2.2.Final-redhat-1.jar:7.2.2.Final-redhat-1]
    at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_55]

http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">

我的 web.xml 文件

<description>resetpwd Web Application</description>
  <display-name>resetpwd</display-name>


  <filter>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <servlet-name>resetpwd</servlet-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>


    <servlet>
        <servlet-name>resetpwd</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath*:spring/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>resetpwd</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- uncomment JPA support persistence unit configuration below -->

    <persistence-unit-ref>
        <persistence-unit-ref-name>persistence/resetpwd-unit</persistence-unit-ref-name>
        <persistence-unit-name>resetpwd-unit</persistence-unit-name>
    </persistence-unit-ref>

    <persistence-context-ref>
    <persistence-context-ref-name>persistence/resetpwd-context</persistence-context-ref-name>
    <persistence-unit-name>resetpwd-unit</persistence-unit-name>
  </persistence-context-ref> 


    <!-- uncomment JPA support persistence unit configuration above -->

     <welcome-file-list>
       <welcome-file>welcome.jsp</welcome-file>
       <welcome-file>welcome.html</welcome-file>
       <welcome-file>index.html</welcome-file>
       <welcome-file>index.jsp</welcome-file>
     </welcome-file-list>

</web-app>

这里是 servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--
    DispatcherServlet context for applications web tier 
-->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:security="http://www.springframework.org/schema/security" 
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:jee="http://www.springframework.org/schema/jee" 
       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/security 
            http://www.springframework.org/schema/security/spring-security.xsd  
            http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx.xsd 
        http://www.springframework.org/schema/jee 
        http://www.springframework.org/schema/jee/spring-jee.xsd                    
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">

    <security:debug/>

    <import resource="servlet-view.xml"/>



     <context:component-scan base-package="edu.ucsd.act.core.resetpwd" />



    <!-- turns on support for mapping requests to Spring MVC @Controller methods. also registers default Formatters and validators for use across all @Controllers -->
    <mvc:annotation-driven conversion-service="conversionService"/> 

    <!--  all resources (css,js,jpg,png,bmp) inside folder (src/main/webapp/resources) are mapped so they can be referred to inside JSP files (see header.jsp for more details) -->
    <mvc:resources mapping="/resources/**" location="/resources/"/>    



    <bean id="expressionHandler" class="edu.ucsd.act.core.coresecurity.requiresaction.MethodExpressionHandler" />


    <!-- static case, no java controller needed --> 
    <mvc:view-controller path="/" view-name="welcome" />

    <!-- serve all static resources (*.html,...) from src/main/webapp/ -->      
    <mvc:default-servlet-handler/>

    <!-- [J] customized -->
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">

        <!-- [1] remove default formatters -->
        <property name="registerDefaultFormatters" value="false" />

        <!-- [2] establish exact formatters that are desired -->
        <property name="formatters">
            <set>
                <bean class="org.springframework.format.number.NumberFormatAnnotationFormatterFactory" />
                <!-- add additional business formatters here -->
            </set>
        </property>

        <!-- [3] alter formatter to match your business requirement -->
        <property name="formatterRegistrars">
            <set>
                <bean class="org.springframework.format.datetime.joda.JodaTimeFormatterRegistrar">
                    <property name="dateFormatter">
                        <bean class="org.springframework.format.datetime.joda.DateTimeFormatterFactoryBean">
                            <property name="pattern" value="yyyyMMdd"/>
                        </bean>
                    </property>
                </bean>
            </set>
        </property>
    </bean>

    <!--
        - Message source for this context, loaded from localized "messages_xx" files.
        - Files are stored inside src/main/resources
    -->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource" p:basename="messages/messages" p:fallbackToSystemLocale="false"/>

    <!-- [J] register "global" interceptor beans to apply to all registered HandlerMappings -->
    <mvc:interceptors>
        <bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"/>
        <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang"/>
    </mvc:interceptors> 

    <!-- [J] store preferred language configuration in a cookie -->
    <bean class="org.springframework.web.servlet.i18n.CookieLocaleResolver" id="localeResolver" p:cookieName="locale"/>

    <!-- [J] resolves localized <theme_name>.properties files in the classpath to allow for theme support, store configuration in a cookie 
    <bean class="org.springframework.ui.context.support.ResourceBundleThemeSource" id="themeSource"/>
    <bean class="org.springframework.web.servlet.theme.CookieThemeResolver" id="themeResolver" p:cookieName="theme" p:defaultThemeName="standard"/>
    -->

    <!-- This bean resolves specific types of exceptions to corresponding logical - view names for error views. The default behavior of 
         DispatcherServlet - is to propagate all exceptions to the servlet container: this will happen - here with all other types of exceptions. -->
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">

        <!-- view name resolved using bean of type InternalResourceViewResolver (declared in servlet-view.xml) -->
        <property name="defaultErrorView" value="exception"/>

        <!-- results into 'WEB-INF/views/exception.jsp' -->
        <property name="warnLogCategory" value="warn"/>

        <property name="exceptionMappings">
            <props>
                <!-- spring security -->
                <prop key="org.springframework.security.access.AccessDeniedException">/403</prop>
            </props>
        </property>
     </bean>

    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver">
        <property name="order" value="1"/>
    </bean>
    <bean class="org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver" >
        <property name="order" value="2"/>
    </bean>

    <!-- developer may wish to further customize final exception handler -->
    <bean class="edu.ucsd.act.core.resetpwd.util.AppHandlerExceptionResolver">
        <property name="order" value="3"/>
    </bean>

    <!-- Enable this for eventual integration of file upload functionality
    <bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver" />
    -->

    <tx:annotation-driven mode="aspectj"
        transaction-manager="transactionManager" />

    <bean id="app" class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
 <jee:jndi-lookup id="resetpwd-unit" jndi-name="persistence/resetpwd-unit" />

</beans>


public Map<String, String> validate() throws IOException {

advancedValidation(errors);

}


public void advancedValidation(Map<String, String> errors) {



        if (!id.contains("@") && md.findByRacf()) {
            // found a unique affiliate based on racf (may be primary or
            // secondary)
        } else if (id.contains("@") && md.findByEmail()) {
            // found a unique affiliate based on email
        } else {
            // a unique affiliate record could not be located
            errors.put("id", "resetpw.nouiserinfo");
            return;
        }

【问题讨论】:

  • 发布真实代码,发布完整的异常堆栈跟踪。
  • 使用字段注入或构造函数注入。不需要两者都做。
  • 你在哪里调用advancedValidation?

标签: java spring autowired


【解决方案1】:

您在ResetPasswordForm 类中声明了两个构造函数。可能,Spring-container 可能为同一类创建了一个重复的实例,一个是 with parameter,另一个是 default constructor。尝试删除默认的构造函数创建。它应该可以工作。

【讨论】:

    【解决方案2】:

    试试这个。只要您始终如一,此范例就有效:

    @Service
    public class MetaData implements MetaDataService {
    
       public boolean findByEmail() {
          this.affiliateRepository.someMethod();
          // some logic
       }
    
       //I like to autowire at the bottom - keep all the glamour up front
       @Autowired
       private AffiliateRepository affiliateRepository;
    }
    

    您的其他服务:

    @Service
    public class ResetPasswordForm implements ResetPasswordFormService {
    
       public ResetPasswordForm() {}
    
       public void advancedValidation(Map<String, String> errors) {
    
            if (someJunk) {
            }
            else if (id.contains("@") && metaData.findByEmail()) {
            }
            else {
            }
       }
    
       //your ORM, if you have one, may complain if this is an interface
       @Autowired
       private MetaData metaData;
    }
    

    我通常不使用EntityManager(我使用SessionFactory),但我想它会是这样的:

    @Repository
    @Transactional
    public class AffiliateRepositoryImpl implements AffiliateRepository, Serializable {
    
       @PersistenceContext
       private EntityManager entityManager;
    
       @SuppressWarnings("unchecked")
       @Transactional(readOnly = true, timeout = 10)
       public List<Affiliate> findAffiliate(String value) {
         // calls to database
       }
    }
    

    您应该检查您的persistence.xml 以确保它与持久性单元的defined 正确。

    【讨论】:

      【解决方案3】:

      我想到的只有一种可能的解释:您加载了多个上下文,并且实际上有两个不同的发生 NPE 的类的 bean 实例——一个带有注入的依赖项,一个没有注入依赖项(导致 NPE)。

      由于您使用 Spring mvc,您可以查看 hereherehere 以获取有关可能原因的更多信息。

      【讨论】:

      • 您好,我已经添加了我的 web.xml 和 servlet-context.xml 文件,请您查看一下,因为我认为我创建的上下文不超过一个。
      • @Myrna 您能否发布您调用advancedValidation 的代码?
      • 我在上面的问题中添加了高级验证。请你看看主要问题。
      • 我的意思是,你能显示调用advancedValidation 方法的代码吗?更准确地说,如何获取调用此方法的ResetPasswordForm 实例?
      • 私有 MetaDataService md; @Autowired public ResetPasswordForm(MetaDataService md) { this.md = md; // 当 iam 调试时,我可以看到此时 bean 被注入。 }
      猜你喜欢
      • 2020-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多