这是我的config.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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com">
<context:include-filter type="assignable" expression="com.coc.frmwk.cmd.Command"/>
<context:include-filter type="assignable" expression="com.coc.apps.sample.dao.SampleDAO"/>
</context:component-scan>
<bean id="myPostProcessor" class="com.coc.frmwrk.processors.MyPostProcessor">
</beans>
我知道在使用组件扫描时,将分配给bean的默认范围是“singleton”,除非在xml配置中另外指定或使用注释@Scope,这很酷,但是因为我已经想到了在我的应用程序中,实现特定接口(com.coc.frmwk.cmd.Command)的所有bean都需要将其范围设置为“prototype”,所以我添加了一个实现ScopeMetaDataResolver的类“ScopeResolver”,我做了这个修改我的config.xml,以便容器考虑我的范围解析器:
<context:component-scan base-package="com" scope-resolver="com.coc.frmwk.processors.ScopeResolver">
我的问题是BeanPostProcessor曾经工作得很好,但每当我添加范围解析器时它就会停止被调用(context:component-scan base-package =“com” scope-resolver =“com.xxx。 frmwk.processors.ScopeResolver“),当我省略粗体内容时,它再次起作用。
在配置ScopeResolver时如何使BeanPostProcessor工作? 谢谢,迈赫迪。
修改:这是我的范围解析程序的内容
package com.coc.frmwk.processors;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ScopeMetadata;
import org.springframework.context.annotation.ScopeMetadataResolver;
import com.coc.frmwk.cmd.Command;
public class ScopeResolver implements ScopeMetadataResolver{
@SuppressWarnings("unchecked")
@Override
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
ScopeMetadata result = new ScopeMetadata();
Class c= null;
try {
c = Class.forName(definition.getBeanClassName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
if (Command.class.isAssignableFrom(c))
result.setScopeName("prototype");
else
result.setScopeName("singleton");
System.out.println("[Scope Resolver] " + definition.getBeanClassName() + "[" + result.getScopeName() + "]");
return result;
}
}
Edit2:我想指出BeanPostProcessor实际上是被调用的,但显然它适用于所有bean,除了那些由ScopeMeteDataResolver改变其范围的bean。
答案 0 :(得分:3)
您描述的行为是我期望的行为。 (至少在启动时),只要构造bean就调用BeanPostProcessor
,只在请求时才构造原型范围的bean。因此,如果您不在任何地方使用此bean,则BeanPostProcessor
将不会被调用。
然而,根据您的需要判断您想要修改配方(BeanDefinition
而不是创建的bean实例)。要查看食谱,您需要使用BeanFactoryPostProcessor
。
不同之处在于BeanPostProcessor
对bean实例进行操作,其中BeanFactoryPostProcessor
适用于bean创建配方(BeanDefinitions
)。
答案 1 :(得分:1)
我还没有找到确切的解决问题的方法,但我确实找到了解决方法,这可能对任何有同样问题的人都有用。
而不是使用BeanPostProcessor和MetaDataScopeResolver的组合,我决定使用BeanFactoryPostProcessor来管理范围分辨率和bean处理。
这里是任何感兴趣的人的BeanFactoryPostProcessor的代码:
@Component
public class OaliaBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@SuppressWarnings("unchecked")
public void postProcessBeanFactory(
ConfigurableListableBeanFactory beanFactory) throws BeansException {
for(String beanName : beanFactory.getBeanDefinitionNames())
{
//Scope resolution
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
Class beanClass= null;
try {
beanClass = Class.forName(beanDefinition.getBeanClassName());
} catch (ClassNotFoundException e) {
// exception handling goes here
}
if (Command.class.isAssignableFrom(beanClass))
beanDefinition.setScope("prototype");
//Stuff that the BeanPostProcessor do go here
//..........
//..........
System.out.println("[Post Processing] " + beanName + " [" + beanDefinition.getScope() + "]");
}
}
}