2016-07-21 19 views
0

Ich bin in dieses Problem für eine Weile fest und kann nicht schlafen: CSpring BeanPostProcessor kann keinen Proxy erstellen, wenn der BeanPostProcessor vom Ziel abhängig ist?

wenn ich BeanPostProcessor verwenden Proxy für einen Beana zu erstellen (BeanPostProcessor nicht auf Beana abhängen), Proxy arbeitet well.But wenn BeanPostProcessor auf Beana abhängen, es nicht work.and ich fand Beana nicht in Spring Application proxied wenn BeanPostProcessor davon abhängen wird

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(); 

erster Fall: proxyBeanProcessor nicht auf targeta hängen

<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"/> 

Ausgang:

advice intercept.... 
targetA is working... 

Bohne in application enter image description here

zweiten Fall: proxyBeanProcessor hängen von 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> 

Ausgang:

targetA is working... 

Bean in der Anwendung:

enter image description here

Antwort

0

Wenn Ihr BeanPostProcessor Bohne auf der Bohne hängt Sie Proxy

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

dann die Bohne unbedingt erstellt werden müssen, wollen vor Ihrer ProxyProcessor Bean ist bereit. Und wenn es nicht bereit ist, kann es keine anderen Beans verarbeiten, einschließlich Ihrer Ziel-Bean.


Wenn Frühling Ihre Bohnen initialisiert, es gibt sie in allen registrierten BeanPostProcessor Bean-Instanzen. Dies bedeutet, dass die Beans BeanPostProcesser bereits initialisiert wurden. Ihr Fall zeigt ein Szenario, in dem eine Bean vor einer BeanPostProcessor initialisiert wird, die sie daher nicht verarbeiten kann.

+0

tkx, Ich habe versucht, auf andere Bean (nicht Ziel Bean) und Proxy funktioniert beim Aufruf der target.work() -Methode.Only abhängig von Ziel funktioniert nicht – fendar

+0

@fendar Es geht um die Reihenfolge der Initialisierung hier.Wenn Ihr 'BeanPostProcessor' vollständig vor dem Ziel initialisiert wurde, kann ** es ** nachbearbeiten. Wenn der 'BeanPostProcessor' nicht vollständig initialisiert ist, weil er vom Ziel abhängt, kann er ** ihn nicht ** nachbearbeiten. –

+0

also gibt es eine Möglichkeit, die ich tun kann, um das Problem zu lösen – fendar