Spring AOP如何让内部方法调用也发生代理

方法之间的调用直接使用的是原始对象,而非代理对象,因而内部调用不会产生代理

public class Waiter {
    public void greetTo(String name) {
        System.out.println("greet to :" + name);
    }

    public void serveTo(String name) {
        System.out.println("serve to :" + name);
        greetTo(name);
    }
public class Seller {
    public void greetTo(String name) {
        System.out.println("greet to :" + name);
    }
}
    <bean id="waiter" class="com.demo.aop.Waiter"/>
    <bean id="seller" class="com.demo.aop.Seller"/>
    <bean class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"
          p:patterns=".*To.*">
        <property name="advice">
            <bean class="com.demo.aop.GreetingAdvice"/>
        </property>
    </bean>
    <!--自动根据advisor生成代理-->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
          p:proxyTargetClass="true"/>

测试类:

@ContextConfiguration(locations = {"classpath:spring-context.xml"})
public class Test extends AbstractJUnit4SpringContextTests {
    @org.junit.Test
    public void test1() {
        Waiter waiter = (Waiter) applicationContext.getBean("waiter");
        Seller seller = (Seller) applicationContext.getBean("seller");
        System.out.println("---------------------------");
        waiter.greetTo("John");
        System.out.println("---------------------------");
        waiter.serveTo("Ivern");
        System.out.println("---------------------------");
        seller.greetTo("Lili");
    }
}

结果:greet方法的内部调用没有生成代理



修改:

/**
 * 自动装配代理对象接口
 */
public interface BeanSelfProxyAware {
    void setBeanSelfProxy(Object proxyObj);
}
/**
 * 自定义容器启动插件
 */
public interface SystemBootAddon extends Ordered {
    void onReady();
}
/**
 * 自定义管理器,当启动完成时,对实现了BeanSelfProxyAware接口的bean注入proxyBean
 */
public class BeanSelfProxyMonter implements ApplicationContextAware, SystemBootAddon {
    private ApplicationContext applicationContext;

    public void onReady() {
        Map<String, BeanSelfProxyAware> proxyAwares = applicationContext.getBeansOfType(BeanSelfProxyAware.class);
        for (BeanSelfProxyAware proxyAware : proxyAwares.values()) {
            proxyAware.setBeanSelfProxy(proxyAware);
        }
    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }
}
/**
 * 消息监听器,监听Spring系统消息
 */
public class SystemBootManager implements ApplicationListener<ContextRefreshedEvent> {
    private List<SystemBootAddon> systemBootAddons;
    private boolean hasRunOnce = false;

    /**
     * Spring自动注入所有的SystemBootAddon
     *
     * @param systemBootAddons
     */
    @Autowired
    public void setSystemBootAddons(List<SystemBootAddon> systemBootAddons) {
        this.systemBootAddons = systemBootAddons;
    }

    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        if (!hasRunOnce) {
            for (SystemBootAddon systemBootAddon :systemBootAddons) {
                systemBootAddon.onReady();
            }
            hasRunOnce = true;
        }
    }
}
<bean id="waiter" class="com.demo.aop.Waiter"/>
    <bean id="seller" class="com.demo.aop.Seller"/>
    <bean class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"
          p:patterns=".*To.*">
        <property name="advice">
            <bean class="com.demo.aop.GreetingAdvice"/>
        </property>
    </bean>
    <!--自动根据advisor生成代理-->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
          p:proxyTargetClass="true"/>
    <!--注册启动器-->
    <bean class="com.demo.aop.BeanSelfProxyMonter"/>
    <!--注册启动加载器-->
    <bean class="com.demo.aop.SystemBootManager"/>
public class Waiter implements BeanSelfProxyAware {
    private Waiter waiterProxy;

    public void setBeanSelfProxy(Object proxyObj) {
        this.waiterProxy = (Waiter) proxyObj;
    }

    public void greetTo(String name) {
        System.out.println("greet to :" + name);
    }

    public void serveTo(String name) {
        System.out.println("serve to :" + name);
        waiterProxy.greetTo(name);
    }
}

最后的结果:







阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页