当前位置: 首页 > 知识库问答 >
问题:

实现ApplicationContextAware-ApplicationContext为空

柏夕
2023-03-14

我正在编写一个Tomcat应用程序,它充当一些内部服务的代理。

我已经将Spring项目从基于XML和注释的混合配置切换到基于Java和注释的配置。

import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

public class MyAppSpringBoot implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) throws ServletException {
        initRootContext(container);
        initDispatcherContext(container);
        addFilters(container);
    }

    private void initDispatcherContext(ServletContext container) {
        AnnotationConfigWebApplicationContext servletContext = new AnnotationConfigWebApplicationContext();
        servletContext.register(MyAppDispatcherServletContext.class);
        ServletRegistration.Dynamic dispatcher
                = container.addServlet("myAppDispatcherServlet", new DispatcherServlet(servletContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }

    private void initRootContext(ServletContext container) {
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(MyAppRootContext.class);
        container.addListener(new ContextLoaderListener(rootContext));
    }

    private void addFilters(ServletContext container) {
        FilterRegistration.Dynamic registration
                = container.addFilter("u3rAuthentication", UserDbAuthenticationFilter.class);
        registration.addMappingForUrlPatterns(null, false, "/entry/*");

        registration = container.addFilter("responseXmlFilter", ResponseTextXmlFilter.class);
        registration.addMappingForUrlPatterns(null, false, "/entry/*");
    }
}
import java.io.File;
import java.io.IOException;
import java.util.Properties;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException;
import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.stereotype.Controller;

@Configuration
@ComponentScan(basePackages = "com.application", excludeFilters = @ComponentScan.Filter(Controller.class))
public class MyAppRootContext {

    @Bean
    public DataSource userDbJpaDataSource() throws DataSourceLookupFailureException {

        JndiDataSourceLookup lookup = new JndiDataSourceLookup();
        return lookup.getDataSource("jdbc/userDbPostgres");
    }

    @Bean
    public EntityManagerFactory entityManagerFactory() {
        //return Persistence.createEntityManagerFactory(MyAppConstants.U3R_PERSISTENCE_UNIT);
        LocalContainerEntityManagerFactoryBean fb = new LocalContainerEntityManagerFactoryBean();
        fb.setDataSource(userDbJpaDataSource());
        return fb.getNativeEntityManagerFactory();
    }

    @Bean
    public DiskFileItemFactory diskFileItemFactory() {
        DiskFileItemFactory factory = new DiskFileItemFactory();
        factory.setSizeThreshold(50_000 * 1024);
        factory.setRepository(new File("/WEB-INF/upload"));
        return factory;
    }

    @Bean
    public XMLOutputFactory xmlOutputFactory() {
        return XMLOutputFactory.newInstance();
    }

    @Bean
    public XMLInputFactory xmlInputFactory() {
        return XMLInputFactory.newInstance();
    }

    @Bean
    public XMLEventFactory xmlEventFactory() {
        return XMLEventFactory.newInstance();
    }

    @Bean
    public UrlPairing urlPairing() throws IOException {
        return new UrlPairing(myAppProperties().getProperty("myApp.UrlPairingFile"));
    }

    @Bean
    public Properties myAppProperties() throws IOException {
        Properties p = new Properties();
        p.load(MyAppRootContext.class.getResourceAsStream("/myAppConfig.properties"));
        return p;
    }

    @Bean
    public MyAppXmlFilterWords xmlFilterWords() throws IOException {
        MyAppXmlFilterWords words = MyAppXmlFilterWords.createFilterWords(myAppProperties().getProperty("myApp.xmlFilterWordFile"));
        return words;
    }

}
@Configuration
@ComponentScan(
        basePackages = "de.lgn.doorman",
        includeFilters = @ComponentScan.Filter(Controller.class)
)
public class MyAppDispatcherServletContext
{
    // all beans are defined in root context
    // correct ???
}

根身份验证筛选器的代码:

@Component
public class UserDbAuthenticationFilter implements Filter, ApplicationContextAware
{
    private static final Logger logger = LogManager.getLogger(UserDbAuthenticationFilter.class.getName());

    @Autowired
    EntityManagerFactory emf;

    private ApplicationContext appContext;

    @Override
    public void init(FilterConfig filterConfig)    
    {
        logger.debug("Filter {} initialisiert. App-Context: {} {}", this.getClass().getName(),appContext.hashCode(), appContext);
        // *******************  NullPointerException here *******************
    }

    @Override
    public void destroy()
    { }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
    {
        appContext = applicationContext;
    }

    /*
    @PostConstruct    // ***************** this annotation isn't working **********************
    public void filterInit() throws ServletException
    {
        logger.debug("Filter {} initialisiert. App-Context: {} {}", this.getClass().getName(),appContext.hashCode(), appContext);
    }

    */
}

在我的控制器中,applicationcontext是正确的(不是null)。

@Controller
@RequestMapping(value = "entry/**")
public class MyAppProxyController implements ApplicationContextAware
{

    @Autowired
    Properties myAppProperties;

    private ApplicationContext appContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
    {
        appContext = applicationContext;
    }

    @PostConstruct
    public void init() throws ServletException   // this is working fine
    {
        logger.debug("Controller {} initialisiert. App-Context: {} {}", this.getClass().getName(),
                appContext.hashCode(), appContext);

        logger.debug("Beans im Zugriff von Controller:");
        for (String beanName : appContext.getBeanDefinitionNames())
        {
            logger.debug("          {}", beanName);
        }
        MyAppProxyController controller = (MyAppProxyController) appContext.getBean("myAppProxyController");
        logger.debug("controller-hash im Controller={}", controller.hashCode());
    }
}    

我遵循了你所有的指示2。但现在我得到了一个例外:

13-Aug-2015 13:03:27.264 INFO [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.ApplicationContext.log Spring WebApplicationInitializers detected on classpath: [de.lgn.doorman.config.DmSpringBoot@c427b4f]
13-Aug-2015 13:03:27.655 INFO [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.ApplicationContext.log Initializing Spring root WebApplicationContext
13-Aug-2015 13:03:28.308 SEVERE [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.StandardContext.filterStart Exception starting filter responseXmlFilter
 org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'responseXmlFilter' is defined
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:698)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1174)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:283)
private void addFilters(ServletContext container)
{
    FilterRegistration.Dynamic registration =
            container.addFilter("userDbAuthenticationFilter", DelegatingFilterProxy.class);
    registration.addMappingForUrlPatterns(null, false, "/mapgate/*");

    registration = container.addFilter("prepareRequestFilter", DelegatingFilterProxy.class);
    registration.addMappingForUrlPatterns(null, false, "/mapgate/*");

    registration = container.addFilter("responseTextXmlFilter", DelegatingFilterProxy.class);
    registration.addMappingForUrlPatterns(null, false, "/mapgate/*");
}
@Configuration
@ComponentScan(basePackages = "com.application", excludeFilters = @ComponentScan.Filter(Controller.class))
public class MyAppRootContext
{

    @Bean
    public UserDbAuthenticationFilter userDbAuthenticationFilter()
    {
        return new UserDbAuthenticationFilter();
    }

    @Bean
    public PrepareRequestFilter prepareRequestFilter()
    {
        return new PrepareRequestFilter();
    }

    @Bean
    public ResponseTextXmlFilter responseTextXmlFilter()
    {
        return new ResponseTextXmlFilter();
    }

    @Bean
    public DataSource userDbJpaDataSource() throws DataSourceLookupFailureException
    {

        JndiDataSourceLookup lookup = new JndiDataSourceLookup();
        return lookup.getDataSource("jdbc/userDbPostgres");
    }

    @Bean
    public EntityManagerFactory entityManagerFactory()
    {
        LocalContainerEntityManagerFactoryBean fb = new LocalContainerEntityManagerFactoryBean();
        fb.setDataSource(userDbJpaDataSource());
        return fb.getNativeEntityManagerFactory();
    }
}
public class U3RAuthenticationFilter implements Filter, ApplicationContextAware
{
    private static final Logger logger = LogManager.getLogger(U3RAuthenticationFilter.class.getName());

    @Autowired(required = true)
    EntityManagerFactory entityManagerFactory;

    private ApplicationContext appContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
    {
        appContext = applicationContext;
    }

    @PostConstruct
    public void filterInit() throws ServletException
    {
        logger.debug("Filter {} initialisiert. App-Context: {} {}", this.getClass().getName(),appContext.hashCode(), appContext);
        logger.debug("Beans accessable by {}:", this.getClass().getName());
        for (String beanName : appContext.getBeanDefinitionNames())
        {
            logger.debug("          {}", beanName);
        }

        logger.debug("EntityManagerFactory: {}", (EntityManagerFactory)appContext.getBean("entityManagerFactory"));
    }
}
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1] controller-hash im Controller=1481031354
20150814-090718 INFO  [RMI TCP Connection(3)-127.0.0.1] Mapped "{[/mapgate/**],methods=[GET]}" onto protected void com.application.controller.MyAppProxyController.doGet(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
20150814-090718 INFO  [RMI TCP Connection(3)-127.0.0.1] Mapped "{[/mapgate/**],methods=[POST]}" onto protected void com.application.controller.MyAppProxyController.doPost(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws javax.servlet.ServletException,java.io.IOException
20150814-090718 INFO  [RMI TCP Connection(3)-127.0.0.1] Looking for @ControllerAdvice: WebApplicationContext for namespace 'myAppDispatcherServlet-servlet': startup date [Fri Aug 14 09:07:18 CEST 2015]; parent: Root WebApplicationContext
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1] Filter com.application.filter.UserDbAuthenticationFilter initialisiert. App-Context: 641348200 WebApplicationContext for namespace 'myAppDispatcherServlet-servlet': startup date [Fri Aug 14 09:07:18 CEST 2015]; parent: Root WebApplicationContext
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1] Beans accessable by com.application.filter.UserDbAuthenticationFilter:
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           org.springframework.context.annotation.internalConfigurationAnnotationProcessor
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           org.springframework.context.annotation.internalAutowiredAnnotationProcessor
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           org.springframework.context.annotation.internalRequiredAnnotationProcessor
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           org.springframework.context.annotation.internalCommonAnnotationProcessor
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           org.springframework.context.annotation.internalPersistenceAnnotationProcessor
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           org.springframework.context.event.internalEventListenerProcessor
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           org.springframework.context.event.internalEventListenerFactory
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           myAppDispatcherServletContext
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           myAppRootContext
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           myAppProxyController
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           requestMappingHandlerMapping
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           mvcContentNegotiationManager
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           viewControllerHandlerMapping
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           beanNameHandlerMapping
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           resourceHandlerMapping
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           mvcResourceUrlProvider
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           defaultServletHandlerMapping
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           requestMappingHandlerAdapter
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           mvcConversionService
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           mvcValidator
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           mvcPathMatcher
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           mvcUrlPathHelper
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           mvcUriComponentsContributor
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           httpRequestHandlerAdapter
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           simpleControllerHandlerAdapter
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           handlerExceptionResolver
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           mvcViewResolver
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           userDbAuthenticationFilter
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           prepareRequestFilter
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           responseTextXmlFilter
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           myAppFilterChain
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           userDbJpaDataSource
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           <b>entityManagerFactory</b>
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           diskFileItemFactory
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           xmlOutputFactory
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           xmlInputFactory
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           xmlEventFactory
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           urlPairing
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           myAppProperties
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1]           xmlFilterWords
20150814-090718 DEBUG [RMI TCP Connection(3)-127.0.0.1] <b>EntityManagerFactory: null</b>

共有1个答案

景令秋
2023-03-14

当应用程序上下文被正确地注入到控制器中时,我假设Spring被正确地初始化了。但是您的筛选器被声明为原始筛选器,而不是spring bean,因此忽略它们上的spring注释。

您有两种方法可以访问应用程序上下文:

>

  • 原始筛选器(未启用Spring)可以通过webapplicationcontext webapplicationcontextutils.getwebapplicationcontext(ServletContext sc)访问根应用程序上下文。例如,可以更改init方法:

    @Override
    public void init(FilterConfig filterConfig)    
    {
        ServletContex sc = filterConfig.getServletContext();
        appContext = WebApplicationContextUtils.getWebApplicationContext(sc);
        logger.debug("Filter {} initialisiert. App-Context: {} {}", this.getClass().getName(),appContext.hashCode(), appContext);
    }
    
    private void addFilters(ServletContext container) {
        FilterRegistration.Dynamic registration
                = container.addFilter("u3rAuthentication", DelegatingFilterProxy.class);
        registration.addMappingForUrlPatterns(null, false, "/entry/*");
    
        registration = container.addFilter("responseXmlFilter", DelegatingFilterProxy.class);
        registration.addMappingForUrlPatterns(null, false, "/entry/*");
    }
    
    @Bean
    public UserDbAuthenticationFilter u3rAuthentication() { 
        return new UserDbAuthenticationFilter();
    }
    
    @Bean
    public ResponseTextXmlFilter responseXmlFilter() { 
        return new ResponseTextXmlFilter();
    }
    

    将不再调用init方法,但这将起作用:

    @PostConstruct
    public void filterInit() throws ServletException
    {
        logger.debug("Filter {} initialisiert. App-Context: {} {}", this.getClass().getName(),appContext.hashCode(), appContext);
    }
    

  •  类似资料:
    • 主要内容:1.BeanFactory 的实现,2.ApplicationContext 的实现,3.BeanFactory 和 ApplicationContext的总结1.BeanFactory 的实现 1.1 DefaultListableBeanFactory 实现类 无解析@Bean. @Configuration 的功能 下面代码解析: 先是通过一个工具类得到BeanDefinition, 然后beanFactory 注册BeanDefinition 打印出工厂种的Bean 下面代码通

    • 问题内容: 在春季,如果实现了bean ,则它可以访问。因此,它能够获得其他豆类。例如 然后可以得到bean的“名称”。 要做到这一点,我们应该把这个里面的,如 这里的bean 不包含属性。我想当spring bean初始化时,就设置了这个属性。但是,这是怎么做的呢?该方法如何调用? 问题答案: 当spring实例化bean时,它会寻找几个接口,例如和。如果找到它们,则将调用这些方法。例如(非常简

    • 4.8. ApplicationContext beans包提供了以编程的方式管理和操控bean的基本功能,而context包下的ApplicationContext以一种更加面向框架的方式增强了BeanFactory的功能。多数用户可以采用声明的方式来使用ApplicationContext,甚至不用手动创建它,而通过ContextLoader这样的支持类,把它作为J2EE web应用的一部分自

    • 在spring中,如果一个bean实现了,那么它就能够访问。因此它能够得到其他的豆子。例如。 为此,我们应该将这个放在中,例如。 这里的bean不包括属性。我猜当spring bean初始化时,这个属性就被设置了。但这是怎么做到的呢?如何调用方法?

    • 问题内容: 我对Spring Framework还是很陌生,我一直在研究它,并将一些示例应用程序放在一起,以评估Spring MVC以便在即将到来的公司项目中使用。到目前为止,我非常喜欢我在Spring MVC中看到的内容,它似乎非常易于使用,并鼓励您编写对单元测试非常友好的类。 作为练习,我正在为我的一个样本/测试项目编写一种主要方法。我不清楚的一件事是BeanFactory和之间的确切差异Ap

    • 我有一个Springboot应用程序,它在运行时根据用户传递的输入参数从中查找bean。对于这种方法,我试图编写Mockito测试用例,但它不起作用,并抛出NullPointerException。 引导应用程序的类: 我试图为其编写测试用例的类: 我的测试用例如下: 每当我运行测试用例时,它都会在