Java 弹簧罐';在servlet上下文和contextConfigLocation bean之间看不到bean

Java 弹簧罐';在servlet上下文和contextConfigLocation bean之间看不到bean,java,spring,spring-mvc,jakarta-ee,spring-bean,Java,Spring,Spring Mvc,Jakarta Ee,Spring Bean,我有一个spring mvc项目,设置如下: appServlet org.springframework.web.servlet.DispatcherServlet 上下文配置位置 /WEB-INF/spring contexts/servlet-context.xml 1. 上下文配置位置 /WEB-INF/spring contexts/configuration-context.xml 如果我在configuration-context.xml中创建了一个bean,并在servlet

我有一个spring mvc项目,设置如下:


appServlet
org.springframework.web.servlet.DispatcherServlet
上下文配置位置
/WEB-INF/spring contexts/servlet-context.xml
1.
上下文配置位置
/WEB-INF/spring contexts/configuration-context.xml

如果我在configuration-context.xml中创建了一个bean,并在servlet-context.xml中引用了一个bean,那么它就找不到它了。这些是作为两种不同的上下文创建的吗?一般来说,为什么会发生这种情况?

是的,有两个上下文相互堆叠(父上下文和子上下文)

DispatcherServlet(
servlet context.xml
)中的bean可以从ContextLoaderListener(
configuration context.xml
)访问bean,但反过来不行

因此,将基本内容放入
configuration context.xml
中,并将与web相关的内容放入
servlet context.xml


@另请参见此堆栈溢出问题:

Spring容器可以明确地看到由上下文的组件扫描基本包决定的组件,并且您可以从上下文中获取bean

spring中有两种类型的上下文
1.根上下文(ApplicationContext)
2.Servlet上下文(WebApplicationContext)

rootContext中定义的bean对servletContext的可见性-是 默认情况下,在根上下文中定义的bean在所有servlet上下文中始终可见。例如,根上下文中定义的数据源bean可以在servlet上下文中访问,如下所示

@Configuration
@ComponentScan(basePackages = { "com.your.configuration.package", "org.springframework.web.servlet" })
public class RootConfiguration
@配置
公共类根配置
{
@豆子
公共数据源数据源()
{
...
}
}
@配置
@EnableWebMvc
@组件扫描(basePackages=“com.pvn.mvctiles”)
公共类ServletConfiguration实现WebMVCConfiguer
{
@自动连线
私有数据源;
...
}
servletContext中定义的bean对rootContext的可见性-是* (为什么*是)
1.上下文顺序的初始化是rootContext优先,servletContext其次。 在根上下文配置类/xml中,如果尝试获取在servletContext中定义的bean,则将得到NULL。(因为servletContext尚未初始化,因此我们可以说在初始化rootContext时bean不可见)

但是,您可以在servletContext初始化之后获得在servletContext中定义的bean(您可以通过应用程序上下文获得bean)

您可以打印并通过以下方式进行确认:

applicationContext.getBeanDefinitionNames();

2.如果您想在过滤器或另一个servlet上下文中访问servlet上下文的bean,请将
“org.springframework.web.servlet”
基本包添加到根配置类/xml中

@配置
@ComponentScan(basePackages=“org.springframework.web.servlet”)
公共类根配置
添加后,您可以从应用程序上下文获得以下所有bean

springSecurityConfig
tileConfigure
themeSource
themeResolver
messageSource
localeResolver
requestMappingHandlerMapping
mvcPathMatcher
mvcUrlPathHelper
mvccontentnegotionmanager
viewControllerHandlerMapping
beanNameHandlerMapping
resourceHandlerMapping
mvcResourceUrlProvider
defaultServletHandlerMapping
requestMappingHandlerAdapter
mvcValidator
MVCuricComponentContributor
httpRequestHandlerAdapter
simpleControllerHandlerAdapter
handlerExceptionResolver
mvcViewResolver
mvcHandlerMappingIntrospector

如果您想从rootContext获取自定义bean,请将基本包值添加到rootContext组件扫描,如下所示

@Configuration
@ComponentScan(basePackages = { "com.your.configuration.package", "org.springframework.web.servlet" })
public class RootConfiguration
如果您希望注入的依赖项在rootContext中可用,并且可以在servlet过滤器中访问,那么上述给定的配置将非常有用。例如,如果您在筛选器中捕获异常,并希望发送与
HttpMessageConverter
发送的响应相同的错误响应,但它是在servletContext中配置的,则您可能希望访问该配置的转换器以发送相同的响应。

注意,下面的自动连接在servlet过滤器中不起作用

@Autowired
private ApplicationContext appContext;
这在servlet过滤器中不起作用,因为过滤器是在spring容器初始化之前初始化的。(取决于过滤器和DelegatingProxyFilter的顺序)

因此,要在筛选器中获取applicationContext

public class YourFilter implements Filter
{
    private ApplicationContext appContext;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException
    {
        Filter.super.init(filterConfig);
        appContext = WebApplicationContextUtils.getRequiredWebApplicationContext(filterConfig.getServletContext());
    }
}

希望它能清楚地说明如何在上下文之间访问bean。

您能告诉我为什么我不能从web servlet访问applicationContext中定义的txManager吗?