使用DefaultAdvisorAutoProxyCreator实现spring的自动代理

标签: defaultadvisorautoproxycreator spring 代理 | 发表时间:2015-12-11 01:01 | 作者:bijian1013
出处:http://www.iteye.com

        DefaultAdvisorAutoProxyCreator这个类功能更为强大,这个类的奇妙之处是他实现了BeanProcessor接口,当ApplicationContext读如所有的Bean配置信息后,这个类将扫描上下文,寻找所有的Advistor(一个Advisor是一个切入点和一个通知的组成),将这些Advisor应用到所有符合切入点的Bean中。

工程结构图:

业务接口:

package com.bijian.study;

public interface Shopping {
	
	public String buySomething(String type);

	public String buyAnything(String type);

	public String sellSomething(String type);

	public String sellAnything(String type);
}

业务实现类:

package com.bijian.study;

public class ShoppingImplA implements Shopping {
	
    private Customer customer;
    
    public Customer getCustomer() {
        return customer;
    }
    public void setCustomer(Customer customer) {
        this.customer = customer;
    }
    public String buySomething(String type) {
        System.out.println(this.getCustomer().getName()+" bye "+type+" success");
        return null;
    }
    
    public String buyAnything(String type) {
       System.out.println(this.getCustomer().getName()+" bye "+type+" success");
       return null;

     }
    public String sellAnything(String type) {
        System.out.println(this.getCustomer().getName()+" sell "+type+" success");
        return null;
    }
    public String sellSomething(String type) {
         System.out.println(this.getCustomer().getName()+" sell "+type+" success");
           return null;
    }
}
package com.bijian.study;

public class ShoppingImplB implements Shopping {
	
    private Customer customer;
    
    public Customer getCustomer() {
        return customer;
    }
    public void setCustomer(Customer customer) {
        this.customer = customer;
    }
    public String buySomething(String type) {
        System.out.println(this.getCustomer().getName()+" bye "+type+" success");
        return null;
    }
    
    public String buyAnything(String type) {
       System.out.println(this.getCustomer().getName()+" bye "+type+" success");
       return null;

     }
    public String sellAnything(String type) {
        System.out.println(this.getCustomer().getName()+" sell "+type+" success");
        return null;
    }
    public String sellSomething(String type) {
         System.out.println(this.getCustomer().getName()+" sell "+type+" success");
           return null;
    }
}

通知:

package com.bijian.study;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

//前置通知
public class WelcomeAdvice implements MethodBeforeAdvice {

  public void before(Method method, Object[] args, Object obj)
          throws Throwable {
      
      System.out.println("Hello welcome to bye ");
  }
}

普通Bean类:

package com.bijian.study;

public class Customer {

	private String name;
	private int age;
	
	public Customer(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	public String getName() {
		return name;
	}
}

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
  "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <bean id="WelcomeAdvice" class="com.bijian.study.WelcomeAdvice"></bean>

	<!-- 自动代理所有的advisor -->
	<bean id="autoProxyCreator"
		class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
	</bean>

	<bean id="advisor"
		class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
		<property name="pattern">
			<value>.*sell.+</value>  <!-- 业务实现方法名匹配 -->
		</property>
		<property name="advice">
			<ref bean="WelcomeAdvice" />
		</property>
	</bean>

	<bean id="buyBean" class="com.bijian.study.ShoppingImplA">
		<property name="customer">
			<ref bean="customer" />
		</property>
	</bean>
	<bean id="sellBean" class="com.bijian.study.ShoppingImplB">
		<property name="customer">
			<ref bean="customer" />
		</property>
	</bean>

	<bean id="customer" class="com.bijian.study.Customer">
		<constructor-arg index="0">
			<value>gaoxiang</value>
		</constructor-arg>
		<constructor-arg index="1">
			<value>26</value>
		</constructor-arg>
	</bean>
</beans>

        我们配置一个advisor,方法和在我的blog关于静态切入点的用正则表达式配置切入点相同,这里匹配的是业务实现类中所有型如:***sell***的方法。

        buyBean和sellBean是最为普通的IOC配置,重点在autoProxyCreator中,我们只需配置一个id(id非必需)和class,spring会自动帮我们解析advisor,并将通知进行切入。

测试程序:

package com.bijian.study.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.bijian.study.Shopping;

public class TestAdvisor {

    public static void main(String[] args) {

//    	String filePath=System.getProperty("user.dir")+File.separator+"src"+File.separator+"applicationContext.xml";
//        ApplicationContext ctx=new FileSystemXmlApplicationContext(filePath);
        
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        
        Shopping shoppingA=null;
        Shopping shoppingB=null;
        
        shoppingA=(Shopping)ctx.getBean("buyBean");
        shoppingB=(Shopping)ctx.getBean("sellBean");
        shoppingA.buySomething("something");
        shoppingA.buyAnything("anything");
        shoppingB.sellAnything("anything");
        shoppingB.sellSomething("something");
    }
}

        需要注意的是:和BeanNameAutoProxyCreator相同,我们需要用ApplicationContext获得Bean。运行结果:

gaoxiang bye something success
gaoxiang bye anything success
Hello welcome to bye 
gaoxiang sell anything success
Hello welcome to bye 
gaoxiang sell something success

        可以看到我们定义的所有***sell***的方法,都被切入了前置通知。

 

PS:在执行时如报java.lang.NoClassDefFoundError: org/aopalliance/aop/Advice错,是少了aopalliance包,这个包涉及到动态织入。是spring的常用联盟包,必不可少。





已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [defaultadvisorautoproxycreator spring 代理] 推荐:

使用DefaultAdvisorAutoProxyCreator实现spring的自动代理

- - 编程语言 - ITeye博客
        DefaultAdvisorAutoProxyCreator这个类功能更为强大,这个类的奇妙之处是他实现了BeanProcessor接口,当ApplicationContext读如所有的Bean配置信息后,这个类将扫描上下文,寻找所有的Advistor(一个Advisor是一个切入点和一个通知的组成),将这些Advisor应用到所有符合切入点的Bean中.

从代理到Spring事务

- - xiaobaoqiu Blog
1.3 CGLib动态代理. 2.3 Aspectj实现. 最近再项目中发现不少同事不理解默认情况下的Spring事务的AOP机制,导致随意使用事务注解.因此也在很多场景事务不生效. 因此想从代理机制开始理一下整个Spring声明式的原理. 通常,我们代码中处理核心的业务逻辑,还包含一些枝节性的代码和功能,比如日志记录、消息发送、安全、事务保证和监控等.

Spring AOP 代理机制 JDK&CGLIB

- - 开源软件 - ITeye博客
Spring AOP使用JDK动态代理或者CGLIB来为目标对象创建代理. (建议优先使用JDK的动态代理). 如果被代理的目标对象实现了至少一个接口,则会使用JDK动态代理. 所有该目标类型实现的接口都将被代理. 若该目标对象没有实现任何接口,则创建一个CGLIB代理. 如果你希望强制使用CGLIB代理,(例如:希望代理目标对象的所有方法,而不只是实现自接口的方法) 那也可以.

Spring AOP动态代理原理与实现方式 (转)

- - 开源软件 - ITeye博客
AOP:面向切面、面向方面、面向接口是一种横切技术. 1.事务管理: (1)数据库事务:(2)编程事务(3)声明事物:Spring AOP-->声明事物   . 3.安全验证: Spring AOP---OOP升级  . 静态代理原理:目标对象:调用业务逻辑    代理对象:日志管理. 表示层调用--->代理对象(日志管理)-->调用目标对象.

被事务代理的spring service 不能使用注解方式发布dubbo服务的问题解决

- - 企业架构 - ITeye博客
       使用 @com.alibaba.dubbo.config.annotation.Service 发布dubbo服务的时候,当服务类没有加入@Transactional的时候没有问题..        但是当加入事务后,spring bean 事务代理, dubbo的 AnnotationBean 扫描 类执行下面的代码的时候就获取不到对应的注解,也就发布不了服务:.

Spring详解

- - CSDN博客架构设计推荐文章
Spring是一个开源的控制反转(Inversion of Control ,IoC)和面向切面(AOP)的容器框架.它的主要目的是简化企业开发.. PersonDaoBean 是在应用内部创建及维护的. 所谓控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的.

Spring定时

- - 行业应用 - ITeye博客
spring的定时任务配置分为三个步骤:. . . . . .

简单Spring+hessian

- - Web前端 - ITeye博客
简单的Spring+hessian. dist\modules里面的 spring-webmvc.jar . lib\caucho 里面的hessian-3.1.3.jar. 里面有个接口interface:. 建立一个model层:(实现Serializable接口). 在WEB-INF下面创建一个remoting-servlet.xml:.

Spring MVC 和 Struts2

- - CSDN博客架构设计推荐文章
Web层面的框架学习了三个Struts1和2,SpringMVC,那他们之间肯定存在一个优劣和适用的环境,Struts1和2的异同点我已经做过对比《 Struts1和Struts2》,这篇将对比下Struts2和SpringMVC的异同,下面数据基本来源于网络,本人是搜集整理所得,供大家参考. 一个项目使用什么样的技术,决定的因素很多,我所能想到的有:对系统的性能、开发的效率、团队学习的成本、业务场景等,下面尽量从这几个方面入手,来分析比较下他们之间存在的优劣.

Spring AOP详解

- - Java - 编程语言 - ITeye博客
        最近项目中遇到了以下几点需求,仔细思考之后,觉得采用AOP来解决. 一方面是为了以更加灵活的方式来解决问题,另一方面是借此机会深入学习Spring AOP相关的内容. 例如,以下需求不用AOP肯定也能解决,至于是否牵强附会,仁者见仁智者见智. 1.对部分函数的调用进行日志记录,用于观察特定问题在运行过程中的函数调用情况.