Spring 当beanPostProcessor 依赖target 时BeanPostProcessor 不能创建代理?
Spring BeanPostProcessor can not create proxy when beanPostProcessor is depend on target?
我在这个问题上卡了一段时间无法解决sleep:C
当我使用 beanPostProcessor 为 beanA 创建代理时(beanPostProcessor 不依赖于 beanA),代理工作 well.But 如果 beanPostProcessor 依赖于 beanA,则它不工作 work.And 我发现 beanA 没有被代理Spring beanPostProcessor 依赖时的 ApplicationContext
目标人脸:
public interface TargetIface {
void work();
}
目标A:
public class TargetA implements TargetIface {
public void work() {
System.out.println("targetA is working...");
}
}
目标B:
public class TargetB implements TargetIface {
public void work() {
System.out.println("targetB is working...");
}
}
简单顾问:
public class SimpleAdvisor extends DefaultPointcutAdvisor {
private TargetIface targetIface;
private final Advice advice = new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("advice intercept....");
if (invocation.getThis().equals(targetIface)) {
System.out.println("my advice");
}
//no adivce
return invocation.proceed();
}
};
public SimpleAdvisor() {
setAdvice(advice);
}
public void setTargetIface(TargetIface targetIface) {
this.targetIface = targetIface;
}
}
beanPostProcessor:
public class ProxyProcessor implements BeanPostProcessor {
private List<Advisor> advisors;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof TargetIface) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(bean);
proxyFactory.addAdvisors(advisors);
return proxyFactory.getProxy();
}
return bean;
}
public void setAdvisors(List<Advisor> advisors) {
this.advisors = advisors;
}
}
主类:
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/Application-context.xml");
TargetA targetA = context.getBean(TargetA.class);
targetA.work();
首先case:proxyBeanProcessor不依赖targetA
<bean id="proxyBeanProcessor" class="net.fendar.test.spring.processor.ProxyProcessor">
<property name="advisors">
<list>
<bean class="net.fendar.test.spring.advisor.SimpleAdvisor">
<!--<property name="targetIface" ref="targetA"/>-->
</bean>
</list>
</property>
</bean>
<bean id="targetA" class="net.fendar.test.spring.bean.TargetA"/>
<bean id="targetB" class="net.fendar.test.spring.bean.TargetB"/>
输出:
advice intercept....
targetA is working...
applicationContext 中的 beanenter image description here
秒 case:proxyBeanProcessor 取决于目标,
<bean id="proxyBeanProcessor" class="net.fendar.test.spring.processor.ProxyProcessor">
<property name="advisors">
<list>
<bean class="net.fendar.test.spring.advisor.SimpleAdvisor">
<property name="targetIface" ref="targetA"/>
</bean>
</list>
</property>
</bean>
<bean id="targetA" class="net.fendar.test.spring.bean.TargetA"/>
<bean id="targetB" class="net.fendar.test.spring.bean.TargetB"/>
<bean id="proxyBeanProcessor" class="net.fendar.test.spring.processor.ProxyProcessor">
<property name="Target" ref="Target"/>
</bean>
输出:
targetA is working...
应用程序中的 bean:
如果您的 BeanPostProcessor
bean 取决于您要代理的 bean
<bean id="proxyBeanProcessor" class="net.fendar.test.spring.processor.ProxyProcessor">
<property name="Target" ref="Target"/>
</bean>
那么必须在您的 ProxyProcessor
bean 准备好之前创建该 bean。而且,如果它还没有准备好,那么它就无法 post 处理任何其他 bean,包括您的目标 bean。
当 Spring 初始化您的 bean 时,它会通过所有已注册的 BeanPostProcessor
bean 实例传递它们。这意味着 BeanPostProcesser
beans 已经被初始化。您的案例演示了一个场景,其中一个 bean 在 BeanPostProcessor
之前被初始化,因此无法处理它。
我在这个问题上卡了一段时间无法解决sleep:C
当我使用 beanPostProcessor 为 beanA 创建代理时(beanPostProcessor 不依赖于 beanA),代理工作 well.But 如果 beanPostProcessor 依赖于 beanA,则它不工作 work.And 我发现 beanA 没有被代理Spring beanPostProcessor 依赖时的 ApplicationContext
目标人脸:
public interface TargetIface {
void work();
}
目标A:
public class TargetA implements TargetIface {
public void work() {
System.out.println("targetA is working...");
}
}
目标B:
public class TargetB implements TargetIface {
public void work() {
System.out.println("targetB is working...");
}
}
简单顾问:
public class SimpleAdvisor extends DefaultPointcutAdvisor {
private TargetIface targetIface;
private final Advice advice = new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("advice intercept....");
if (invocation.getThis().equals(targetIface)) {
System.out.println("my advice");
}
//no adivce
return invocation.proceed();
}
};
public SimpleAdvisor() {
setAdvice(advice);
}
public void setTargetIface(TargetIface targetIface) {
this.targetIface = targetIface;
}
}
beanPostProcessor:
public class ProxyProcessor implements BeanPostProcessor {
private List<Advisor> advisors;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof TargetIface) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(bean);
proxyFactory.addAdvisors(advisors);
return proxyFactory.getProxy();
}
return bean;
}
public void setAdvisors(List<Advisor> advisors) {
this.advisors = advisors;
}
}
主类:
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/Application-context.xml");
TargetA targetA = context.getBean(TargetA.class);
targetA.work();
首先case:proxyBeanProcessor不依赖targetA
<bean id="proxyBeanProcessor" class="net.fendar.test.spring.processor.ProxyProcessor">
<property name="advisors">
<list>
<bean class="net.fendar.test.spring.advisor.SimpleAdvisor">
<!--<property name="targetIface" ref="targetA"/>-->
</bean>
</list>
</property>
</bean>
<bean id="targetA" class="net.fendar.test.spring.bean.TargetA"/>
<bean id="targetB" class="net.fendar.test.spring.bean.TargetB"/>
输出:
advice intercept....
targetA is working...
applicationContext 中的 beanenter image description here
秒 case:proxyBeanProcessor 取决于目标,
<bean id="proxyBeanProcessor" class="net.fendar.test.spring.processor.ProxyProcessor">
<property name="advisors">
<list>
<bean class="net.fendar.test.spring.advisor.SimpleAdvisor">
<property name="targetIface" ref="targetA"/>
</bean>
</list>
</property>
</bean>
<bean id="targetA" class="net.fendar.test.spring.bean.TargetA"/>
<bean id="targetB" class="net.fendar.test.spring.bean.TargetB"/>
<bean id="proxyBeanProcessor" class="net.fendar.test.spring.processor.ProxyProcessor">
<property name="Target" ref="Target"/>
</bean>
输出:
targetA is working...
应用程序中的 bean:
如果您的 BeanPostProcessor
bean 取决于您要代理的 bean
<bean id="proxyBeanProcessor" class="net.fendar.test.spring.processor.ProxyProcessor">
<property name="Target" ref="Target"/>
</bean>
那么必须在您的 ProxyProcessor
bean 准备好之前创建该 bean。而且,如果它还没有准备好,那么它就无法 post 处理任何其他 bean,包括您的目标 bean。
当 Spring 初始化您的 bean 时,它会通过所有已注册的 BeanPostProcessor
bean 实例传递它们。这意味着 BeanPostProcesser
beans 已经被初始化。您的案例演示了一个场景,其中一个 bean 在 BeanPostProcessor
之前被初始化,因此无法处理它。