Spring 8:AOP advice & adivsor

※ Spring中AOP的实现:AOP(Aspect Oriented Programming) 面向切面编程

    spring中AOP功能的实现有以下俩种情况:
        1.如果目标对象实现了接口,默认情况下会采用JDK的动态代理来实现AOP功能
        2.如果目标对象没有实现接口,spring会使用CGLIB的库来实现代理类实现AOP功能

    注:spring会在JDK动态代理和CGLIB之间自动选择

※ 认识AOP中的一些基本概念,然后在一个一个的例子中,不断的加强对这些概念的理解,同时要能自己表述出每个概念的含义
 

   AOP          面向切面编程

   aspect       切面/切面类

   joinPoint    连接点
            在spring的aop中只有 类中的方法 可以做连接点,每一个方法都可以是一个连接点.
        
   pointCut     切入点
            一组连接点的集合

   advice       通知/拦截器
            用来控制切面类将来到底是织入到切入点的前面、后面或者是抛异常的时候。

   adivsor(通知+切面(选择生效的方法))    增强器
            用来筛选类中的哪些方法是我们的连接点(哪些方法需要被拦截).

   target       目标对象

   proxy        代理对象

   wave         织入(让通知在连接点上生效)

    -----------------------

    ※ advice(通知)的类型:

        前置通知(Before advice):
            在某些连接点(join point)之前执行的通知

        返回后通知(After returning advice):
            在某些连接点(join point)正常完成后执行的通知(方法正常结束,没有异常)

        抛出异常后通知(After throwing advice):
            在某些连接点(join point)抛出异常退出时执行的通知

        后通知(After (finally) advice):
            当某些连接点(join point)退出的时候执行的通知

        环绕通知(Around Advice):
            包围一个连接点(join point)的通知,例如事务的处理,就需要这样的通知,因为事务需要在方法前开启,在方法后提交,以及方法抛出异常时候回滚

    注:在spring中,连接点(join point)指的就是方法
    ※ 在Spring中,Advice是由spring中的几个接口来指定,主要有以下几种:
  

    目标接口
    public interface OrderService {
    void saveOrder();
    void deleteOrder();
    String getById(String name);
    }
    目标对象
    public class OrderServiceImpl  implements OrderService{

    @Override
    public void saveOrder() {
        System.out.println("save.....");
    }
    @Override
    public void deleteOrder() {
        System.out.println("delete.....");
    }
    @Override
    public String getById(String name) {
        System.out.println("getById..........");
        return name;
    }
}


    ※ 1 Before Advice


 

   public interface MethodBeforeAdvice extends BeforeAdvice {
        void before(Method m, Object[] args, Object target) throws Throwable;
    }
    例如:
    1,定义前置通知
    public class beforeTest  implements MethodBeforeAdvice{
    @Override
    public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("before  "+arg0.getName()+"--"+arg1+"--"+arg2);
    }

    }
    2,配置映射文件
           <bean name="target"
           class="com.briup.Proxy.staticProxy.OrderServiceImpl"></bean>
           <bean name="before" class="com.briup.aop.brfore.beforeTest"></bean>
               <bean name="proxy"
           class="org.springframework.aop.framework.ProxyFactoryBean">
           <!-- 目标对象 -->
               <property name="target"  ref="target"></property>
               <property name="interfaces">
                   <array>
                       <value>com.briup.Proxy.staticProxy.OrderService</value>
                   </array>
               </property>
               <!-- 通知方式 是数组-->
               <property name="interceptorNames" value="before">
                   <!-- <array>
                       <value>before</value>
                   </array> -->
               </property>
           </bean>
例:
1.前置通知类

package com.briup.AOP.spring.before;

import java.lang.reflect.Method;
import java.util.Arrays;

import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.framework.ProxyFactoryBean;

/*
 * 前置通知:
 * 在目标对象中方法执行之前加入操作
 * 
 */
public class BeforeAdviceTest implements MethodBeforeAdvice{
   /*
    * 第一个参数:目标对象方法的镜像
    * 第二个参数:目标对象方法的参数
    * 第三个参数:目标对象
    */
	@Override
	public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
		// TODO Auto-generated method stub
//		System.out.println(arg0);
//		System.out.println(Arrays.toString(arg1));
//		System.out.println(arg2);
		System.out.println("before...");
		
	}

}


2.配置文件xml(spring直接给出代理类工厂ProxyFactoryBean)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      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.xsd">
<!-- 目标对象 -->
<bean name="target" class="com.briup.pojo.BookServiceImpl"></bean>
<!-- 配置处理器(通知) -->
<bean name="before" class="com.briup.AOP.spring.before.BeforeAdviceTest"></bean>
<!-- 构建代理对象
     ProxyFactoryBean产生代理对象的工厂类
     条件:1.目标对象
          2.目标对象实现的接口(目标对象没有接口忽略)
          3.拦截器(处理器)拦截目标方法(handler) 
          注意:获取代理对象是基于工厂的名字获取的-->
<bean name="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 配置目标对象 -->
<property name="target" ref="target"></property>
<!--配置目标对象实现的接口 -->
<property name="interfaces">
<array>
<value>com.briup.pojo.BookService</value>
</array>
</property>
<!-- 配置通知或增强器 -->
<!-- <property name="interceptorNames" value="before"></property> -->
<property name="interceptorNames">
<array>
<!-- 多个通知 -->
<value>before</value>
<value>before</value>
</array>
</property>
</bean>
<!-- 没有接口采用cglib -->
<bean name="target1" class="com.briup.pojo.ProductService"></bean>
<bean name="proxy1" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 配置目标对象 -->
<property name="target" ref="target1"></property>
<!-- 配置通知或增强器 -->
<!-- <property name="interceptorNames" value="before"></property> -->
<property name="interceptorNames">
<array>
<value>before</value>
</array>
</property>
</bean>
</beans>          


3.测试类

package com.briup.AOP.spring.before;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.briup.pojo.BookService;
import com.briup.pojo.ProductService;

public class BefoerTest {
public static void main(String[] args) {
	ClassPathXmlApplicationContext cp=
			new ClassPathXmlApplicationContext("com/briup/AOP/spring/before/before.xml");
//	BookService bs=(BookService) cp.getBean("proxy");
//	bs.saveBook(1, "lisi");
//	bs.get(1);
	ProductService ps=(ProductService) cp.getBean("proxy1");
	ps.getProduct();
}
}


    ※ 2 After Returning advice


    public interface AfterReturningAdvice extends AfterAdvice {
        void afterReturning(Object returnValue, Method m, Object[] args, Object target) throws Throwable;
    }
    例如:
    1.定义:返回后通知
    public class afterTest implements AfterReturningAdvice{
    @Override
    public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("after.... "+arg0+"--"+arg1.getName()+"--"+arg2[0]+"--"+arg3);
    }
    }
    2.配置xml文件
    <bean name="target" class="com.briup.Proxy.staticProxy.OrderServiceImpl"></bean>
           <bean name="after" class="com.briup.aop.after.afterTest"></bean>
           <bean name="proxy"  class="org.springframework.aop.framework.ProxyFactoryBean">
                       <property name="target" ref="target"></property>
                       <property name="interfaces">
                           <array>
                               <value>com.briup.Proxy.staticProxy.OrderService</value>
                           </array>
                       </property>
                       <property name="interceptorNames" value="after"></property>
           </bean>
例:
1.后置通知:
package com.briup.AOP.spring.after;

import java.lang.reflect.Method;
import java.util.Arrays;

import org.springframework.aop.AfterReturningAdvice;

/*
 * 后置通知:
 * 在目标对象中所有方法执行完成之后执行的操作
 */
public class AfterAdviceTest implements AfterReturningAdvice{
    /*
     * 第一个参数:目标对象方法执行之后的返回值
     * 第二个参数:目标对象执行方法的镜像
     * 第三个参数:目标对象执行方法的参数
     * 第四个参数:目标对象
     */
	@Override
	public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println(arg0);
		System.out.println(arg1);
		System.out.println(Arrays.toString(arg2));
		System.out.println(arg3);
		System.out.println("after...");
	}

}


2.配置文件xml(同before)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      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.xsd">
<bean name="target" class="com.briup.pojo.BookServiceImpl"></bean>
<bean name="after" class="com.briup.AOP.spring.after.AfterAdviceTest"></bean>
<bean name="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="target"></property>
<property name="interfaces">
<array>
<value>com.briup.pojo.BookService</value>
</array>
</property>
<property name="interceptorNames">
<array>
<value>after</value>
</array>
</property>
</bean>
<bean name="target1" class="com.briup.pojo.ProductService"></bean>
<bean name="proxy1" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="target1"></property>
<property name="interceptorNames">
<array>
<value>after</value>
</array>
</property>
</bean>
</beans>

3.测试类

package com.briup.AOP.spring.after;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.briup.pojo.BookService;
import com.briup.pojo.ProductService;

public class AfterTest {
public static void main(String[] args) {
	ClassPathXmlApplicationContext cp=
			new ClassPathXmlApplicationContext("com/briup/AOP/spring/after/after.xml");
//	BookService ps=(BookService) cp.getBean("proxy");
//	ps.saveBook(1, "tom");
//	ps.get(1);
//	ps.list();
	ProductService ps=(ProductService) cp.getBean("proxy1");
	ps.getProduct();
}
}


       ※ 3 环绕Advice


      

  import org.aopalliance.intercept.MethodInterceptor;
        public interface MethodInterceptor extends Interceptor {
          Object invoke(MethodInvocation invocation) throws Throwable;
    }
        例如
    1.定义环绕通知
    public class aroundTest implements  MethodInterceptor{
    @Override
    public Object invoke(MethodInvocation arg0) throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("开始执行方法"+arg0.getMethod().getName());
        Object  o=arg0.proceed();
        System.out.println("执行方法完成"+o);
        return o;
    }
    2.配置映射文件
    <bean name="target" class="com.briup.Proxy.staticProxy.OrderServiceImpl"></bean>
           <bean name="around" class="com.briup.aop.around.aroundTest"></bean>
           <bean name="proxy"  class="org.springframework.aop.framework.ProxyFactoryBean">
                       <property name="target" ref="target"></property>
                       <property name="interfaces">
                           <array>
                               <value>com.briup.Proxy.staticProxy.OrderService</value>
                           </array>
                       </property>
                       <property name="interceptorNames" value="around"></property>
      </bean>
例:
1.环绕通知
package com.briup.AOP.spring.around;

import java.util.Arrays;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class AroundAdviceTest implements MethodInterceptor{
   /*
    * 环绕通知:
    * 目标对象方法执行的前后增加操作
    */
	@Override
	public Object invoke(MethodInvocation arg0) throws Throwable {
		// TODO Auto-generated method stub
		//获取调用目标对象方法的参数
		System.out.println("args:"+Arrays.toString(arg0.getArguments()));
		//获取调用目标对象方法的镜像
		System.out.println(arg0.getMethod());
		//获取目标对象
		System.out.println(arg0.getThis());
		System.out.println("before...");
		//执行目标对象的方法
		Object obj=arg0.proceed();
		System.out.println("after...");
		return null;
	}

}


2.配置文件xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      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.xsd">
<bean name="target" class="com.briup.pojo.BookServiceImpl"></bean>
<!-- 环绕通知 -->
<bean name="around" class="com.briup.AOP.spring.around.AroundAdviceTest"></bean>
<bean name="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="target"></property>
<property name="interfaces">
<array>
<value>com.briup.pojo.BookService</value>
</array>
</property>
<property name="interceptorNames">
<array>
<value>around</value>
</array>
</property>
</bean>
</beans>


3.测试类

package com.briup.AOP.spring.around;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.briup.pojo.BookService;

public class AroundTest {
	public static void main(String[] args) {
		ClassPathXmlApplicationContext cp=
				new ClassPathXmlApplicationContext("com/briup/AOP/spring/around/around.xml");
		BookService ps=(BookService) cp.getBean("proxy");
		ps.saveBook(1, "tom");
		ps.get(1);
		ps.list();
	}
}


      ※ 4 Throws Advice


  

 //ThrowsAdvice 是一个空接口,起标识作用
    public interface ThrowsAdvice extends Advice {

    }
    例如:
    1.定义抛出异常后通知
    public class ThrowATest implements ThrowsAdvice{
    public void afterThrowing(Method method, Object[] args, Object target, Exception ex){
        System.out.println(ex.getMessage()+"     "+method.getName()+"--"+args+"---"+target);
    }
    //下面这样写也可以
        /*
        public void afterThrowing(Exception e) {
            
            logger.log(e.getMessage());
        }
        */
        2.定义配置文件
        <bean name="target" class="com.briup.Proxy.staticProxy.OrderServiceImpl"></bean>
           <bean name="throwA" class="com.briup.aop.throwA.ThrowATest"></bean>
            <bean name="before" class="com.briup.aop.brfore.beforeTest"></bean>
           <bean name="proxy"  class="org.springframework.aop.framework.ProxyFactoryBean">
                       <property name="target" ref="target"></property>
                       <property name="interfaces">
                           <array>
                               <value>com.briup.Proxy.staticProxy.OrderService</value>
                           </array>
                       </property>
                       <property name="interceptorNames" >
                           <array>
                               <value>throwA</value>
                               <value>before</value>
                           </array>
                       </property>
           </bean>
}
例:
1.异常通知

package com.briup.aop.spring.throwT;

import java.lang.reflect.Method;

import org.springframework.aop.ThrowsAdvice;
/*
 * 异常通知
 * 当执行目标对象方法报错的时候执行
 * 的代码
 */
public class ThrowAdviceTest 
	implements ThrowsAdvice{
	public void afterThrowing(Method method, Object[] args, Object target, Exception ex){
		System.out.println("exception....");
	}
}


2.配置文件

<?xml version="1.0" encoding="UTF-8"?>
  <beans xmlns="http://www.springframework.org/schema/beans"
      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.xsd">
	<bean name="target" 
	class="com.briup.pojo.BookServiceImpl"></bean>
	<!-- 环绕通知 -->
	<bean name="around" 
	class="com.briup.aop.spring.around.AroundAdviceTest"></bean>
	<!-- 异常通知的配置 -->
	<bean name="throwE" 
	class="com.briup.aop.spring.throwT.ThrowAdviceTest"></bean>
	<bean name="proxy" 
	class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="target" ref="target"></property>
		<property name="interfaces">
			<array>
				<value>com.briup.pojo.BookService</value>
			</array>
		</property>
		<property name="interceptorNames">
			<array>
				<value>around</value>
				<value>throwE</value>
			</array>
		</property>
	</bean>
</beans>

3.测试类

package com.briup.aop.spring.throwT;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.briup.pojo.BookService;

public class ThrowTest {
	public static void main(String[] args) {
		ClassPathXmlApplicationContext cp=
				new ClassPathXmlApplicationContext(
						"com/briup/aop/spring/throwT/throw.xml");
		BookService bs=
				(BookService) cp.getBean("proxy");
		//bs.saveBook(1, "jake");
		bs.list();
//		bs.get(1);
	}
}




※ advisor  增强器


    作用:筛选目标对象中要代理的方法,之前是把目标对象中的所有方法全部都进行代理
    1)目标对象
   

<bean name="target" class="com.briup.Proxy.staticProxy.OrderServiceImpl"></bean>


    2)配置增强器
    

           <bean name="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
                       <property name="advice" ref="before"></property>
                       <property name="patterns">
                                       <array>
                                           <value>.*Order</value>
                                       </array>
                       </property>
           </bean>


      3)配置代理对象
              

           <bean name="proxy"  class="org.springframework.aop.framework.ProxyFactoryBean">
                       <property name="target" ref="target"></property>
                       <property name="interfaces">
                           <array>
                               <value>com.briup.Proxy.staticProxy.OrderService</value>
                           </array>
                       </property>
                       <property name="interceptorNames" value="advisor"></property>
           </bean>
           
例:
<?xml version="1.0" encoding="UTF-8"?>
  <beans xmlns="http://www.springframework.org/schema/beans"
      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.xsd">
	<bean name="target" 
	class="com.briup.pojo.BookServiceImpl"></bean>
	<bean name="after" 
	class="com.briup.aop.spring.after.AfterAdviceTest"></bean>
	<bean name="before" 
	class="com.briup.aop.spring.before.BeforeAdviceTest"></bean>
	<!-- 对目标对象中的方法选择只有一部分
	加通知的,用增强器
	advisor=advice+切面(选择生效的方法) -->
	<bean name="advisor" 
	class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
		<!-- 匹配通知 -->
		<property name="advice" ref="before"></property>
		<!-- 匹配生效的方法 
		匹配用目标对象的全包名+类名+方法名
		com.briup.pojo.BookServiceImpl.getAge
		匹配一种模式pattern
		匹配多种模式patterns
		-->
		<property name="patterns">
			<array>
				<value>com.briup.pojo.Book.*save.*</value>
				<value>com.briup.pojo.BookServiceImpl.getAge</value>
			</array>
		</property>
	</bean>
	<bean name="proxy" 
	class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="target" ref="target"></property>
		<property name="interfaces">
			<array>
				<value>com.briup.pojo.BookService</value>
			</array>
		</property>
		<!-- 配置通知或增强器 -->
		<property name="interceptorNames">
			<array>
				<value>advisor</value>
				<value>after</value>
			</array>
		</property>
	</bean>
</beans>


package com.briup.aop.spring.advisor;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.briup.pojo.BookService;

public class advisorTest {
	public static void main(String[] args) {
		ClassPathXmlApplicationContext cp=
				new ClassPathXmlApplicationContext(
						"com/briup/aop/spring/advisor/advisor.xml");
		BookService bs=
				(BookService) cp.getBean("proxy");
		bs.saveBook(1, "jake");
//		bs.list();
//		bs.get(1);
//		bs.getAge();
	}
}



            ※ 同时产生多个代理对象


           通过名字进行自动代理:BeanNameAutoProxyCreator类的使用
           使用原因:虽然自动代理可以很方便的给xml文件中的目标对象设置对应的代理对象,但是并不是xml文件中的所有对象都是我们的目标对象,我们更想希望可以进一步筛选出某几个对象为我们的目标对象
            名字进行自动代理:解决了上面的问题,给我们提供了筛选目标对象的配置方式
           1)目标对象(包含实现接口|没有实现接口)
           

           <bean name="target" class="com.briup.Proxy.staticProxy.OrderServiceImpl"></bean>
           <bean name="target1" class="com.briup.Proxy.staticProxy.OrderServiceImpl"></bean>
           <bean name="target2" class="com.briup.Proxy.staticProxy.OrderServiceImpl"></bean>


            2)配置增强器
            

           <bean name="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
                       <property name="advice" ref="before"></property>
                       <property name="patterns">
                                       <array>
                                           <value>.*Order</value>
                                       </array>
                       </property>
           </bean>


           3)配置xml文件
            

            <bean name="proxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
                         <property name="beanNames">
                             <array>
                                 <value>us</value>
                                 <value>target</value>
                                 <value>target1</value>
                                 <value>target2</value>
                             </array>
                         </property>
                         <property name="interceptorNames">
                             <array>
                                 <value>advisor</value>
                             </array>
                         </property>
             </bean>


             注意:
             使用byName自动代理的时候需要注意的方面:
            1.当前的配置里面"有没有"advisor的配置"都没关系"
            2.需要向自动代理类中注入被代理目标对象的名字已经advice或者advisor
            3.不管目标对象是否实现了一个或多接口,自动代理的方式都能够为它产生代理对象.
            4.从spring容器中拿代理对象的时候,需要通过目标对象的名字来拿。
            
       

多个代理对象的配置

1.前置通知

package com.briup.aop.spring.moreProxy;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class BeforeAdbiceTest 
	implements MethodBeforeAdvice{

	@Override
	public void before(Method method, Object[] args, Object target) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("before....");
	}

}


2.配置文件(实体类BookService.java,BookServiceImpl.java,ProductService.java略)xml

<?xml version="1.0" encoding="UTF-8"?>
  <beans xmlns="http://www.springframework.org/schema/beans"
      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.xsd">
	<bean name="target" 
	class="com.briup.pojo.BookServiceImpl"></bean>
	<bean name="target1"
	 class="com.briup.pojo.ProductService"></bean>
	<!-- 通知 的配置-->
	<bean name="before" 
	class="com.briup.aop.spring.moreProxy.BeforeAdbiceTest"></bean>
	<!-- 增强器=切面+advice -->
	<bean name="advisor"
	 class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
	 	<property name="advice" ref="before"></property>
	 	<property name="patterns" value=".*.save.*"></property>
	 </bean>
	<!-- 多个代理对象的配置
	BeanNameAutoProxyCreator
	1,通知advice或者增强器advisor
	2.配置目标对象
	 -->
	<bean  class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
		<!-- 指定目标对象名字
		获取代理对象基于目标对象名字获取
		 -->
		<property name="beanNames">
			<array>
				<value>target</value>
				<value>target1</value>
			</array>
		</property>
		<!-- 配置通知advice和增强器advisor -->
		<property name="interceptorNames">
			<array>
				<value>advisor</value>
			</array>
		</property>
	</bean>
</beans>



3.测试类:

package com.briup.aop.spring.moreProxy;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.briup.pojo.BookService;
import com.briup.pojo.ProductService;

public class morePrxyTest {
	public static void main(String[] args) {
		ClassPathXmlApplicationContext cp=
				new ClassPathXmlApplicationContext(
						"com/briup/aop/spring/moreProxy/moreProxy.xml");
		BookService bs=
		cp.getBean("target",BookService.class);
		bs.saveBook(1, "lisi");
		bs.list();
		ProductService ps=
				cp.getBean("target1",ProductService.class);
		ps.saveProduct(1, "lisi");
		ps.getProduct();
	}
}


            ※ 自动代理DefaultAdvisorAutoProxyCreator类的使用


            使用原因:在配置文件中我们往往需要给很多个目标对象设置代理对象,那么上面例子的方式就需要每个目标对象的代理对象都需要配置一套类似的标签
            自动代理:可以用很少的配置为xml文件中的目标对象自动的生成对应的代理对象
            1)目标对象
           

           <bean name="target" class="com.briup.Proxy.staticProxy.OrderServiceImpl"></bean>
           <bean name="target1" class="com.briup.Proxy.staticProxy.OrderServiceImpl"></bean>
           <bean name="target2" class="com.briup.Proxy.staticProxy.OrderServiceImpl"></bean>


            2)配置增强器
            

          <bean name="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
                       <property name="advice" ref="before"></property>
                       <property name="patterns">
                                       <array>
                                           <value>.*Order</value>
                                       </array>
                       </property>
           </bean>


               3)配置自动注入标签
          

 <bean name="proxy"  class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
            </bean>


            使用自动代理的时候需要注意的方面:
            1.当前的配置里面"一定要有"一个advisor的配置,否则自动代理不成功
            2.不需要向自动代理类中注入任何信息
            3.不管目标对象是否实现了一个或多接口,自动代理的方式都能够为它产生代理对象(CGLib的方式).
            4.从spring容器中拿代理对象的时候,需要通过目标对象的名字来拿。
            5.spring如何确定配置文件中哪个bean是作为目标对象:
          通过advisor中筛选的方法,如果这个bean中含有advisor中所配置的方法,则这个bean将来称为我们的目标对象进行代理

自动配置增强器

1.配置文件

<?xml version="1.0" encoding="UTF-8"?>
  <beans xmlns="http://www.springframework.org/schema/beans"
      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.xsd">
	<bean name="target" 
	class="com.briup.pojo.BookServiceImpl"></bean>
	<bean name="target1"
	 class="com.briup.pojo.ProductService"></bean>
	<!-- 通知 的配置-->
	<bean name="before" 
	class="com.briup.aop.spring.moreProxy.BeforeAdbiceTest"></bean>
	<!-- 增强器=切面+advice -->
	<bean name="advisor"
	 class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
	 	<property name="advice" ref="before"></property>
	 	<property name="patterns" value=".*"></property>
	 </bean>
	 <!-- 自动完成advsor作用与目标对象
	 上,通过目标对象bean标签的名字
	 获取代理对象 
	 DefaultAdvisorAutoProxyCreator
	 配置的时候至少有一个advisor配置-->
	<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>
</beans>


2.测试类:

package com.briup.aop.spring.autoAdvisor;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.briup.pojo.BookService;
import com.briup.pojo.ProductService;

public class autoAdvisorTest {
	public static void main(String[] args) {
		ClassPathXmlApplicationContext cp=
				new ClassPathXmlApplicationContext(
						"com/briup/aop/spring/autoAdvisor/autoAdvisor.xml");
		BookService bs=
		cp.getBean("target",BookService.class);
		bs.saveBook(1, "lisi");
		bs.list();
		ProductService ps=
				cp.getBean("target1",ProductService.class);
		ps.saveProduct(1, "lisi");
		ps.getProduct();
	}
}

猜你喜欢

转载自blog.csdn.net/qq_42857603/article/details/83349464