Spring (Aspect Oriented Programming)的配置
1、如果对一个对象的方法进行扩充(不改变源码的情况之下,增加或修改行为)的话,一般使用代理模式:
静态代理(太麻烦,一般不会用)- JDK 的动态代理
- CGLib 的动态代理
2、如果直接写代理生成也麻烦了,所以,基于动态代理,产生了 AOP 的编程思想。这里的*扩充*指的是功能分离,实现解耦
3、实际中,基于代理实现的 AOP 方案有很多,比如:
- AspectJ 实现
- Jboss AOP 实现
- Spring AOP 实现
4、Spring AOP
1、默认的情况下Spring AOP是基于JDK代理的,所以它需要接口。
2、它也可以调用CGLib的代理方式(如果两个都没有它只能抛异常或报错)
通知类型
- 前置通知(Before advice): 在某连接点之前执行的通知,但这个通知不能阻止连接点之前的执行流程(除非它抛出一个异常)
- 后置通知(After returning advice): 在某连接点正常完成后执行的通知
- 异常通知(After throwing advice): 在方法抛出异常退出时执行的通知
- 最终通知(After (finally) advice): 当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
- 环绕通知(Around Advice): 包围一个连接点的通知,如方法调用
5、Spring AOP - xml
首先我们创建了一Cat(猫)类和一个AnimalConduct(动物行为)类和一个xml文件 ,其次创建一个测试类
AnimalConduct:
package dynamicProxy.instanceXml5; public class AnimalConduct { public void start() { System.out.println("程序刚刚开始,这只猫不知道要干嘛!"); } public void end() { System.out.println("程序结束还,这只猫跑不动了"); } }
Cat:
package dynamicProxy.instanceXml5; public class Cat { public void to() { System.out.println("这是一只猫"); } }
xml:
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" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="cat" class="dynamicProxy.instanceXml5.Cat"></bean> <bean id="animalConduct" class="dynamicProxy.instanceXml5.AnimalConduct"></bean> <!----> <!--<aop:aspectj-autoproxy/>--> <aop:config> <aop:aspect ref="animalConduct"> <!-- 前置 --> <aop:before method="start" pointcut="execution(* *.*(..))"/> </aop:aspect> </aop:config> </beans>
Test:
package dynamicProxy.instanceXml5; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-aop/spring-aop.xml"); Cat bean = context.getBean(Cat.class); bean.to(); } }
运行的结果:
7、Spring AOP - java 配置
java配置并不是那么的难,我们在使用java配置的时候一定要注解 " execution(* *.*(..))" 配置包的路径,如果使用星号配置,配置不对了,程序是不会给你个报错的
Dog类:
package dynamicProxy.instance4.animal; import org.springframework.stereotype.Component; @Component public class Dog { public void introduced() { System.out.println("社么贵司是否收到"); } }
BankManageMent类:
package dynamicProxy.instance4.bank; import org.springframework.stereotype.Component; @Component public class BankManagement { public void personnel(int number) { System.out.println("银行有多少人:" + number); } }
TypeMethod类:
package dynamicProxy.instance4; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; @Aspect @Component public class TypeMethod { @After("execution(void dynamicProxy.instance4.*.*.*(..))") public void to() { System.out.println("结束做什么事情"); } @Before("execution(void dynamicProxy.instance4.animal.Dog.*(..))") public void before() { System.out.println("开始做什么事情"); } // @AfterReturning("execution(public * *.*(..))") public void AfterReturning() { System.out.println("method AfterReturning"); } }
如果你是写xml,请在xml 中加上这一句
<aop:aspectj-autoproxy/>
如果你是使用java style配置请在容器初始化的开头加上
Test:
package dynamicProxy.instance4; import com.wgc.persons.spring.SpringDAOConfig; import dynamicProxy.instance4.animal.Dog; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringDAOConfig.class); Dog bean = context.getBean(Dog.class); bean.introduced(); } }
运行的结果: