spring06Aop
1.实现前置增强 必须实现接口MethodBeforeAdvice接口
创建对应的文件
public interface Animal {//主业务接口 void eat(); //目标方法 void sleep(); }
public class Dog implements Animal {//目标对象 /* * 专心我们的逻辑 * 至于方法之前和方法之后要做的事情!我不关注! * Ioc:降低了主业务之间的耦合度 * AOP:降低了主业务和交叉业务逻辑之间的耦合度 */ @Override public void eat() { System.out.println("Dog在吃骨头"); } @Override public void sleep() { System.out.println("Dog睡觉"); } }
public class AnimalBeforeAdvice implements MethodBeforeAdvice { /** * method:执行的方法 * args:方法的参数 * target:目标类对象 */ @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("进入 了 前置 增强..............MethodBeforeAdvice"); } }
<?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:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c" 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="dog" class="cn.bdqn.dao.impl.Dog"/> <!-- 配置前置 增强 --> <bean id="before" class="cn.bdqn.advice.AnimalBeforeAdvice"/> <!-- 生成 代理对象 --> <bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 设置目标对象(被代理的对象)<property name="targetName" value="dog"/> --> <property name="target" ref="dog"/> <!-- 设置增强方式 --> <property name="interceptorNames"> <value>before</value> </property> </bean> </beans>
public class AnimalTest { @Test public void test01(){ ApplicationContext context= new ClassPathXmlApplicationContext("applicationContext.xml"); //使用代理对象进行操作 Animal animal=(Animal) context.getBean("proxyFactoryBean"); animal.eat(); System.out.println("************"); animal.sleep(); } }
2.实现后置增强 必须实现接口AfterReturningAdvice接口
public class AnimalAfterAdvice implements AfterReturningAdvice { /** * returnValue:返回值 ,能获取返回值 但是如果对返回值进行了操作!没有意义! * afterReturning()就没有返回值 */ @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("执行了 后置 通知.................AfterReturningAdvice"); } }
<?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:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c" 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="dog" class="cn.bdqn.dao.impl.Dog"/> <!-- 配置前置 通知--> <bean id="before" class="cn.bdqn.advice.AnimalBeforeAdvice"/> <!-- 配置后置 通知--> <bean id="after" class="cn.bdqn.advice.AnimalAfterAdvice"/> <!-- 生成 代理对象 --> <bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 设置目标对象(被代理的对象)<property name="targetName" value="dog"/> --> <property name="target" ref="dog"/> <!-- 设置增强方式 同时配置多个增强方式01 .value="before,after"--> <property name="interceptorNames" > <!-- 02. 使用array <array> <value>before</value> <value>after</value> </array> --> <list> <value>before</value> <value>after</value> </list> </property> </bean> </beans>
测试代码不变 直接运行
3.实现环绕增强 必须实现接口MethodInterceptor接口
public class AnimalAroundAdvice implements MethodInterceptor { /** * * 环绕增强 是在前置增强之后 和后置增强之前 执行! * 可以对方法的返回值进行一系列的操作 */ @Override public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("方法之前........MethodInterceptor"); Object result = invocation.proceed(); //判断是否有返回值 if (result!=null) { result=((String)result).toUpperCase(); } System.out.println("方法之后........MethodInterceptor"); return result; } }
可以修改Animal中的任意一个方法带有返回值的进行测试! 如
public interface Animal {//主业务接口 String eat(); //目标方法 void sleep(); }
public class Dog implements Animal {//目标对象 @Override public String eat() { System.out.println("Dog在吃骨头"); return "abcd"; } @Override public void sleep() { System.out.println("Dog睡觉"); } }
<?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:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c" 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="dog" class="cn.bdqn.dao.impl.Dog"/> <!-- 配置环绕 通知--> <bean id="around" class="cn.bdqn.advice.AnimalAroundAdvice"/> <!-- 生成 代理对象 --> <bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="dog"/> <property name="interceptorNames" > <list> <value>around</value> </list> </property> </bean> </beans>
//测试返回值 @Test public void test02(){ ApplicationContext context= new ClassPathXmlApplicationContext("applicationContext.xml"); //使用代理对象进行操作 Animal animal=(Animal) context.getBean("proxyFactoryBean"); System.out.println(animal.eat()); System.out.println("************"); animal.sleep(); }
效果图
4.实现自定义增强
并不是所有的方法都需要增强,那么我们就需要自定义增强的方法
<?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:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c" 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="dog" class="cn.bdqn.dao.impl.Dog"/> <!-- 配置前置 通知--> <bean id="before" class="cn.bdqn.advice.AnimalBeforeAdvice"/> <!-- 自定义通知的切入点 --> <bean id="myAdvice" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <property name="advice" ref="before"></property> <property name="mappedNames"> <list> <value>eat</value> <!-- eat之外的方法就不会有前置通知了 --> </list> </property> </bean> <!-- 生成 代理对象 --> <bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="dog"/> <property name="interceptorNames" > <list> <value>myAdvice</value> <!--引入自定义增强 --> </list> </property> </bean> </beans>
测试代码不变