首页 > 代码库 > spring06Aop

spring06Aop

技术分享

1.实现前置增强 必须实现接口MethodBeforeAdvice接口

创建对应的文件

技术分享
public interface Animal {//主业务接口    void  eat();  //目标方法    void  sleep();}
Animal接口
技术分享
public class Dog implements Animal {//目标对象    /*     * 专心我们的逻辑       * 至于方法之前和方法之后要做的事情!我不关注!     * Ioc:降低了主业务之间的耦合度     * AOP:降低了主业务和交叉业务逻辑之间的耦合度     */    @Override    public void eat() {        System.out.println("Dog在吃骨头");    }    @Override    public void sleep() {         System.out.println("Dog睡觉");    }}
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="http://www.mamicode.com/dog"/>  -->   <property name="target" ref="dog"/>      <!-- 设置增强方式 -->   <property name="interceptorNames">        <value>before</value>   </property>  </bean> </beans>
applicationContext.xml文件
技术分享
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="http://www.mamicode.com/dog"/>  -->   <property name="target" ref="dog"/>      <!-- 设置增强方式     同时配置多个增强方式01 .value="http://www.mamicode.com/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>
修改后的xml文件

测试代码不变 直接运行 

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();}
改变后的Animal接口
技术分享
public class Dog implements Animal {//目标对象    @Override    public String eat() {        System.out.println("Dog在吃骨头");        return  "abcd";    }    @Override    public void sleep() {         System.out.println("Dog睡觉");    }}
改变后的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>
xml文件
技术分享
//测试返回值    @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>
修改后的xml文件

测试代码不变 

spring06Aop