spring - 5 AOP - 自动代理生成器

自动代理生成器

前面的所有例子中所使用的代理对象,均是由ProxyFactoryBean代 理工具类生成的。

而该代理工具类存在着如下缺点:

1.一个代理对象只能代理一个Bean,即如果有两个Bean同时都要 织入同一个切面,这时,不仅要配置这两个Bean,即两个目标对象,同时 还要配置两个代理对象。

2.在客户类中获取Bean时,使用的是代理类的id,而非我们定义的 目标对象Bean的id。我们真正想要执行的应该是目标对象。从形式上看, 不符合正常的逻辑。 Spring提供了自动代理生成器,用于解决ProxyFactoryBean的问题。 常用的自动代理生成器有两个:

  • 默认advisor自动代理生成器 (DefaultAdvisorAutoProxyCreator)
  • Bean名称自动代理生成器(BeanNameAutoProxyCreator)

DefaultAdvisorAutoProxyCreator会为每一个目标对象织入所有匹配 的Advisor,不具有选择性。而BeanNameAutoProxyCreator的代理生成方式 是,根据bean的id,来为符合相应名称的类生成相应代理对象。

DefaultAdvisorAutoProxyCreator只能切入顾问,BeanNameAutoProxyCreator能切入顾问和通知

 

 

 

DefaultAdvisorAutoProxyCreator演示

1.创建两个通知(前置、后置)

public class MyAfterReturingAdvice implements AfterReturningAdvice {
	/*
	 * @see org.springframework.aop.AfterReturningAdvice#afterReturning(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], java.lang.Object)
	 * returnValue:目标方法返回值
	 * method:目标方法
	 * args:目标方法参数
	 * target:目标类的对象
	 */
	@Override
	public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
		System.out.println("后置通知方法执行!    目标方法返回值:"+returnValue);
	}

}
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
	@Override
	public void before(Method method, Object[] args, Object target) throws Throwable {
		System.out.println("前置通知方法执行!");
	}

}

2.主业务接口和目标类

//主业务接口
public interface IService {
	//目标方法
	void doSome();
	//目标方法
	void doOther();
}
//目标类
public class StudentServiceImpl implements IService {

	@Override
	public void doSome() {
		System.out.println("Student主业务逻辑当中doSome()方法执行!");
	}


	@Override
	public void doOther() {
		System.out.println("Student主业务逻辑当中doOther()方法执行!");

	}
	public void doThird(){
		System.out.println("1111111111111111111111");
	}
	

}
//目标类
public class TeacherServiceImpl implements IService {

	@Override
	public void doSome() {
		System.out.println("Teacher主业务逻辑当中doSome()方法执行!");
	}


	@Override
	public void doOther() {
		System.out.println("Teacher主业务逻辑当中doOther()方法执行!");

	}
	public void doThird(){
		System.out.println("1111111111111111111111");
	}
	

}

3.主配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd"> 
    <!-- 注册目标类 -->  
    <bean id="studentServiceImpl" class="com.bjsxt.service.StudentServiceImpl"/>
    <bean id="teacherServiceImpl" class="com.bjsxt.service.TeacherServiceImpl"/>
    <!-- 注册前置通知 -->  
    <bean id="myMethodBeforeAdvice" class="com.bjsxt.advice.MyMethodBeforeAdvice"/>
    <!-- 注册后置通知 -->  
    <bean id="myAfterReturningAdvice" class="com.bjsxt.advice.MyAfterReturingAdvice"/>
    
    <!-- 注册顾问 -->  
    <bean id="myAdvisor1" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor" >
    	<property name="advice" ref="myMethodBeforeAdvice"/>
    	<property name="mappedName" value="doSome"/>
    </bean>
    <bean id="myAdvisor2" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor" >
    	<property name="advice" ref="myAfterReturningAdvice"/>
    	<property name="mappedName" value="doSome"/>
    </bean>
    
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
</beans>

4.测试

public final class TestMethodBeforeAdvice {
	@Test
	public void test01(){
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		IService proxy = (IService) ac.getBean("studentServiceImpl");
		proxy.doOther();
		proxy.doSome();
		IService proxy1 = (IService) ac.getBean("teacherServiceImpl");
		proxy1.doOther();
		proxy1.doSome();
	}
}

140135_51qF_3519338.png

 

BeanNameAutoProxyCreator演示

其余同上

主配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd"> 
    <!-- 注册目标类 -->  
    <bean id="studentServiceImpl" class="com.bjsxt.service.StudentServiceImpl"/>
    <bean id="teacherServiceImpl" class="com.bjsxt.service.TeacherServiceImpl"/>
    <!-- 注册前置通知 -->  
    <bean id="myMethodBeforeAdvice" class="com.bjsxt.advice.MyMethodBeforeAdvice"/>
    <!-- 注册后置通知 -->  
    <bean id="myAfterReturningAdvice" class="com.bjsxt.advice.MyAfterReturingAdvice"/>
    
    <!-- 注册顾问 -->  
    <bean id="myAdvisor1" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor" >
    	<property name="advice" ref="myMethodBeforeAdvice"/>
    	<property name="mappedName" value="doSome"/>
    </bean>
    <bean id="myAdvisor2" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor" >
    	<property name="advice" ref="myAfterReturningAdvice"/>
    	<property name="mappedName" value="doSome"/>
    </bean>
    
    <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
    	<property name="beanNames" value="studentServiceImpl"/>
    	<property name="interceptorNames" value="myAdvisor2"/>
    </bean>
</beans>
        
    

Student目标类主业务逻辑当中doOther()方法执行!
Student目标类主业务逻辑当中doSome()方法执行!
后置通知方法执行!    目标方法返回值:null
Teacher目标类主业务逻辑当中doOther()方法执行!
Teacher目标类主业务逻辑当中doSome()方法执行!

转载于:https://my.oschina.net/nan99/blog/1517952

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值