BeanPostProcessor 未调用
这是我的 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都需要将其范围设置为“原型”,所以我添加了一个实现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;
}
}
编辑2:我想指出,BeanPostProcessor实际上正在被调用,但显然它适用于除那些具有它们的范围由 ScopeMeteDataResolver 更改。
here's my 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>
I know that when using component-scan, the default scope that will be assigned to the beans is "singleton" unless it's specified otherwise in the xml configuration or using the annotation @Scope, that's cool, but since i've figured out that in my application all the beans implementing a specific interface (com.coc.frmwk.cmd.Command) need to have their scope set to "prototype", so i added a class "ScopeResolver" that implements ScopeMetaDataResolver and i made this little modification to my config.xml so that the container takes into account my scope resolver :
<context:component-scan base-package="com" scope-resolver="com.coc.frmwk.processors.ScopeResolver">
My problem is that the BeanPostProcessor used to work perfectly, but it stops being called whenever i add the scope resolver ( context:component-scan base-package="com" scope-resolver="com.xxx.frmwk.processors.ScopeResolver" ) and it works again when i omit the stuff in bold.
Any idea on how to make The BeanPostProcessor works when the ScopeResolver is configured ?
Thanks, Mehdi.
Edit: here's the content of my scope resolver
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: I want to point out that the BeanPostProcessor is in fact being called, but apparently it works with all the beans except those having their scope changed by the ScopeMeteDataResolver.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您所描述的行为是我所期望的行为。 (至少在启动时),BeanPostProcessor 一旦被构造就会被调用,原型范围的 bean 仅在被请求时才被构造。因此,如果您不在任何地方使用此 bean,则 BeanPostProcessor 将不会被调用。
然而,从您想要的内容来看,您需要修改配方(
BeanDefinition
,而不是创建的 bean 实例)。为了改变配方,您需要使用 BeanFactoryPostProcessor 。不同之处在于,
BeanPostProcessor
对 bean 实例进行操作,而BeanFactoryPostProcessor
对 bean 创建配方(BeanDefinitions
)进行操作。The behavior you describe is the behavior I would expect. (At least at startup), the
BeanPostProcessor
is called as soon as a bean is constructed, a prototype scoped bean is only constructed when it is requested. So if you don't use this bean anywhere theBeanPostProcessor
will not get called.However judging from what you want you want to modify the recipe (the
BeanDefinition
and not so much the created bean instance). For chancing the recipes you need to use aBeanFactoryPostProcessor
.The difference is that a
BeanPostProcessor
operates on bean instances where as theBeanFactoryPostProcessor
works on the bean creation recipes (theBeanDefinitions
).我还没有找到确切的解决方法,但我确实找到了解决方法,这可能对遇到相同问题的任何人都有用。
我决定使用 BeanFactoryPostProcessor 来管理范围解析和 bean 处理,而不是使用 BeanPostProcessor 和 MetaDataScopeResolver 的组合。
这是 BeanFactoryPostProcessor 的代码,供感兴趣的人参考:
I haven't found exactly how to solve the problem, but i did find a workaround, this might be useful for anyone having the same issue.
well instead of using a combination of BeanPostProcessor and a MetaDataScopeResolver, i decided to use a BeanFactoryPostProcessor that manages both the scope resolution and the bean processing.
here'ds the code of the BeanFactoryPostProcessor for anyone interested: