2016-07-21 8 views
0

私はしばらくの間、この問題で立ち往生していますし、眠ることができない:私は(beanPostProcessor beanAに依存しない)beanAのプロキシを作成するためにbeanPostProcessorを使用する場合beanPostProcessorがbeanAに依存している場合、プロキシはwell.But作品CbeanPostProcessorがターゲットに依存している場合、Spring BeanPostProcessorはプロキシを作成できません。

public interface TargetIface { 
    void work(); 
} 

TargetA:

public class TargetA implements TargetIface { 
    public void work() { 
     System.out.println("targetA is working..."); 
    } 
} 
それはないwork.And私はbeanPostProcessorが

TargetIfaceそれに依存したときbeanAは春のApplicationContextにプロキシされていないました

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

最初のケース:のApplicationContext enter image description here

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

ビーン

第二ケース: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> 

、ターゲットに依存する出力: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"/> 

出力に依存しません

targetA is working... 

アプリケーション内のBean:あなたのBeanPostProcessor Beanがプロキシ

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

にしたい豆に依存している場合、あなたのProxyProcessor Beanがある前に

enter image description here

答えて

0

そのBeanは必ずしも作成する必要があります準備ができました。そして、準備ができていなければ、ターゲットBeanを含む他のBeanを処理する方法はありません。


SpringがBeanを初期化すると、登録されているすべてのBeanインスタンスBeanPostProcessorを通過します。これは、BeanPostProcesserのBeanが既に初期化されていることを意味します。あなたのケースは、BeanPostProcessorの前にBeanが初期化されているため、それを処理できないシナリオを示しています。

+0

TKXは、私は他の豆に依存しようとしている(豆を対象としない)とmethod.Onlyがターゲットに依存しないことが、ここで初期化の順序についてのすべてだ@fendar – fendar

+0

を作品)(target.workを呼び出すときにプロキシが働いていました。あなたの 'BeanPostProcessor'がターゲットの前に完全に初期化されていれば、**それを処理することができます**。 'BeanPostProcessor'がターゲットに依存しているため完全に初期化されていなければ**処理できません。 –

+0

これは問題を解決するための方法です。 – fendar

関連する問題