加快织入的自动化进程---DefaultAdvisorAutoProxyCreator

<span style="font-size:18px;">加快织入的自动化进程
  在IoC容器中使用ProxyFactoryBean进行横切逻辑的织入固然不错,但是我们都是针对每个目标对象,然后给出它们各自所对应ProxyFactoryBean配置。
  如果目标对象就那几个,那还应付的过来。但系统中那么多的业务对象可能都是目标对象,如果还用ProxyFactoryBean一个个的进行配置,估计会很累
  所以得寻求更加快捷的方式.SpringAOP给出了自动代理(AutoProxy)机制,用以帮助我们解决ProxyFactoryBean的配置工作量较大的问题。
  Spring AOP的自动代理的实现建立在IOC容器的BeanPostProcessor概念之上,通过BeanPostProcessor,可以在遍历容器中所有bean的基础上,对遍历到
  的bean进行一些操作。根据这个BeanPostProcessor内部实现逻辑,即当对象实例化的时候不,为其生成代理对象并返回,从而达到代理对象自动生成目的。
  
  可用的AutoProxyCreator
  Spring AOP 在org.springframework.aop.framework.autoproxy包中提供了两个常用的AutoProxyCreator,即BeanNameAutoProxyCreator 和  DefaultAdvisorAutoProxyCreator
  
  这里主要来介绍下DefaultAdvisorAutoProxyCreator。
  DefaultAdvisorAutoProxy可以算是全自动的,我们只需要在ApplicationContext的配置文件中注册一个DefaultAdvisorAutoProxy的bean定义就可以了,剩下的事情由
  DefaultAdvisorAutoProxy全部搞定。下面来展示一个具体的实现例子
  
  ICounter接口定义及相关具体实现类
  public interface ICounter {

	void resetCounter();
	int getCounter();
 }
 
 ICounter有两个实现类ICounterImpl1和ICounterImpl2
 
 public class CounterImpl implements ICounter {
	private int counter;
	@Override
	public void resetCounter() {
		// TODO Auto-generated method stub
		counter = 0;
	}
	@Override
	public int getCounter() {
		// TODO Auto-generated method stub
		counter++;
		return counter;
	}
}

public class CounterImpl2 implements ICounter{
	private int counter;
	@Override
	public void resetCounter() {
		// TODO Auto-generated method stub
		counter=10;
	}
	@Override
	public int getCounter() {
		// TODO Auto-generated method stub
		counter--;
		return counter;
	}
}

ITask接口定义及相关实现类
public interface ITask {
	void execute();
}

ITask也有两个实现类 MockTask 和 FakeTask

public class MockTask implements ITask{
	@Override
	public void execute() {
		// TODO Auto-generated method stub
		System.out.println("taskmock executed");
	}
}

public class FakeTask implements ITask{
	@Override
	public void execute() {
		// TODO Auto-generated method stub
		System.out.println(" facktask executed");
	}
}

我还自定义了一个简单的拦截类PerformanceMethodInterceptor,可以应用到具体的类或其方法中

public class PerformanceMethodInterceptor implements MethodInterceptor{
	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		System.out.println("start.....");//相当于beforeAvice
		Object returnVal=invocation.proceed();
		System.out.println("stop....");//相当于AfterAdvice
		return returnVal;
	}
}

DefaultAdvisorAutoProxyCreator的使用配置示例
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

	xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-2.5.xsd
        http://www.springframework.org/schema/tx
         http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

	<bean
		class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>
	<bean id="counterImpl1" class="aop.spring.deleIntroduction.CounterImpl1"></bean>
	<bean id="counterImpl2" class="aop.spring.deleIntroduction.CounterImpl2"></bean>

	<bean id="mockTask" class="aop.spring.deleIntroduction.MockTask"></bean>
	<bean id="fakeTask" class="aop.spring.deleIntroduction.FakeTask"></bean>


	<bean name="pointcut"
		class="org.springframework.aop.support.NameMatchMethodPointcut">
		<property name="mappedName" value="execute"></property>
	</bean>
	<!-- 有多个方法时 -->
	<bean name="pointcut2" class="org.springframework.aop.support.NameMatchMethodPointcut">
		<property name="mappedNames">
		<list>
		<value>resetCounter</value>
		<value>getCounter</value>
		</list>
		</property>
	</bean>

	<bean id="logAdvisor1" class="org.springframework.aop.support.DefaultPointcutAdvisor">
		<property name="pointcut" ref="pointcut"></property>
		<property name="advice">
			<bean id="performaceInterceptor1"
				class="aop.spring.deleIntroduction.PerformanceMethodInterceptor">
			</bean>
		</property>
	</bean>


	<bean id="logAdvisor2" class="org.springframework.aop.support.DefaultPointcutAdvisor">
		<property name="pointcut" ref="pointcut2"></property>
		<property name="advice">
			<bean id="performaceInterceptor2" class="aop.spring.deleIntroduction.PerformanceMethodInterceptor"></bean>
		</property>
	</bean>
</beans>


  将DefaultAdvisorAutoProxyCreator注册到容器后,它就会自动搜寻容器类所有Advisor,然后根据各个Advisor所提供的拦截信息,
  为符合条件的容器中的目标对象生成相应的代理对象。注意DefaultAdvisorAutoProxyCreator只对Advisor有效,因为只有Advisor
  才既有Pointcut信息以捕捉符合条件的目标对象,又有相应的Advice。
  使用DefaultAdvisorAutoProxyCreator对容器内所有bean定义对应的对象进行自动代理之后,我们从容器中取得对象实例,就都是代理
  后已经包含了织入的横切逻辑的代理对象了,除非该对象不符合Pointcut规定的拦截条件。
  
  建立一个测试类如下
  
  public class AutoProxyCreaterTest {
	@Test
	public void test() {
		ApplicationContext ctx=new ClassPathXmlApplicationContext("/beans1.xml");
		ITask task1=(ITask) ctx.getBean("mockTask");
		task1.execute();
		ITask task2=(ITask) ctx.getBean("fakeTask");
		task2.execute();
		ICounter counter1=(ICounter) ctx.getBean("counterImpl1");
		System.out.println(counter1.getCounter());
		ICounter counter2=(ICounter)ctx.getBean("counterImpl1");
		System.out.println(counter2.getCounter());
		ICounter counter3=(ICounter)ctx.getBean("counterImpl2");
		System.out.println(counter3.getCounter());
	}
}

输出的结果如下:
start.....
task executed
stop....

start.....
 facktask executed
stop....

start.....
stop....
1

start.....
stop....
2

start.....
stop....
-1

从结果可以看出每个对象都被加上了横切逻辑
所以这里  ITask task1=(ITask) ctx.getBean("mockTask");这些返回的都不是目标对象本身而是被织入了横切逻辑的对象。
通过自己动手实践,我基本上就了解了DefaultAdvisorAutoProxy的用法了。
真的是动手实践很重要很重要.























</span>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值