当BeanPostProcessor依赖于目标时,Spring BeanPostProcessor无法创建代理?

时间:2016-07-21 18:05:20

标签: java spring spring-aop cglib

我陷入这个问题已经有一段时间无法入睡:C

当我使用beanPostProcessor为beanA创建代理(beanPostProcessor不依赖于beanA)时,代理工作正常。但是如果beanPostProcessor依赖于beanA,它就不起作用。我发现当beanPostProcessor依赖时,beanA在Spring ApplicationContext中没有代理在它上面

TargetIface:

public interface TargetIface {
    void work();
}

TargetA:

public class TargetA implements TargetIface {
    public void work() {
        System.out.println("targetA is working...");
    }
}

TargetB:

public class TargetB implements TargetIface {
    public void work() {
        System.out.println("targetB is working...");
    }
}

SimpleAdivsor:

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;
}
}

mainClass:

ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/Application-context.xml");
    TargetA targetA = context.getBean(TargetA.class);
    targetA.work();

第一种情况: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 enter image description here

中的

bean

第二种情况:proxyBeanProcessor依赖于Target,

<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:

enter image description here

1 个答案:

答案 0 :(得分:0)

如果您的BeanPostProcessor bean依赖于您想要代理的bean

<bean id="proxyBeanProcessor" class="net.fendar.test.spring.processor.ProxyProcessor">
    <property name="Target" ref="Target"/>
</bean>

然后必须在ProxyProcessor bean准备好之前创建该bean。并且,如果它还没有准备好,那么它就无法发布任何其他bean,包括你的目标bean。

当Spring初始化bean时,它会将它们传递给所有已注册的BeanPostProcessor bean实例。这意味着BeanPostProcesser bean已经初始化。您的案例演示了在BeanPostProcessor之前初始化bean的情况,因此无法处理它。