spring aop实现

来源:互联网 发布:弱碱性水的好处 知乎 编辑:程序博客网 时间:2024/06/06 06:37

AOP面向切面编程的四种实现

          一.AOP(面向切面编程)的四种实现分别为最原始的经典AOP、代理工厂bean(ProxyFacteryBean)和默认自动代理DefaultAdvisorAutoProxyCreator以及BeanNameAutoProxyCreator代理、Aspectj的注解和xml配置文件。

     1.代理工厂bean(ProxyFacteryBean)的方式

      1.1 接口(Interface)

 

复制代码
1 package cn.happy.interfaces;2 3 public interface Advice {4 5     public void fristMethod();6     7     public String secondMethod();8 }
复制代码

         1.2  接口的实现类

复制代码
 1 package cn.happy.impl; 2  3 import cn.happy.interfaces.Advice; 4  5 public class AdviceImpl implements Advice { 6  7     public void fristMethod() { 8          System.out.println("==fristMethod=="); 9     }10 11     public String secondMethod() {12         System.out.println("==secondMethod==");13         return "abc";14     }15 16 }
复制代码

 

 

         1.3 各种通知增强

       1.3.1 前置增强

复制代码
 1 package cn.happy.advice; 2  3 import java.lang.reflect.Method; 4  5 public class MethodBeforeAdvice implements 6         org.springframework.aop.MethodBeforeAdvice { 7  8     public void before(Method arg0, Object[] arg1, Object arg2) 9             throws Throwable {10         System.out.println("==Before==");11          12     }13 14 }
复制代码

 

 

        1.3.2  后置增强

复制代码
 1 package cn.happy.advice; 2  3 import java.lang.reflect.Method; 4  5 import org.springframework.aop.AfterReturningAdvice; 6  7 public class AfterReturningAdvie implements AfterReturningAdvice { 8  9     public void afterReturning(Object arg0, Method arg1, Object[] arg2,10             Object arg3) throws Throwable {11         System.out.println("==After==");12 13     }14 15 }
复制代码

 

 

      1.3.3  环绕增强

复制代码
package cn.happy.aroundadvice;import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;public class MyInterceptor implements MethodInterceptor{    public Object invoke(MethodInvocation invocation) throws Throwable {        System.out.println("==before==");        String result= (String)invocation.proceed();        System.out.println("==after==");        return result;    }}
复制代码

 

        

      1.3.4 异常增强

复制代码
package cn.happy.exception;import org.springframework.aop.ThrowsAdvice;public class MyException implements ThrowsAdvice {    public void afterThrowing(Exception ex){        System.out.println("异常通知");    }}
复制代码

 

        

         1.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: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="adviceimpl" class="cn.happy.impl.AdviceImpl"></bean>       <!-- 前置增强  通知-->        <bean id="advicebefore" class="cn.happy.advice.MethodBeforeAdvice"></bean>        <!-- 后置增强  通知-->        <bean id="adviceafter" class="cn.happy.advice.AfterReturningAdvie"></bean>                <!-- 环绕增强 -->        <bean id="around" class="cn.happy.aroundadvice.MyInterceptor"></bean>                <!-- 关联  代理工厂bean ProxyFacteryBean 通知 -->        <!--<bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">                      <property name="targetName" value="adviceimpl"></property>           <property name="interceptorNames" value="advicebefore,adviceafter"></property>                   </bean>-->                <!-- 环绕增强 代理工厂 顾问包装通知 -->        <bean id="aroundserviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">                      <property name="target" ref="adviceimpl"></property>           <property name="interceptorNames" value="beforeadvisor"></property>                   </bean>                <!-- 切面  通知  -->        <bean id="beforeadvice" class="cn.happy.mymethodbefore.MyMethodBeforeAdvice"></bean>                <!-- 顾问  包装advice -->        <bean id="beforeadvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">         <property name="advice" ref="beforeadvice"></property>         <property name="mappedNames" value="fristMethod,secondMethod"></property>        </bean>                <!-- 顾问  包装advice 正则表达式-->        <!--<bean id="beforeadvisor1" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">         <property name="advice" ref="beforeadvice"></property>         <property name="pattern" value=".*Method.*"></property>        </bean>-->                        <!-- 默认自动代理  默认只找通知-->        <!--<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>-->                <!-- beanname自动代理 可以选择顾问或者通知-->        <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">          <property name="beanNames" value="adviceimpl"></property>          <property name="interceptorNames" value="beforeadvisor"></property>        </bean>        </beans>
复制代码

 

  

       1.5 测试类

复制代码
package cn.happy.test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import cn.happy.interfaces.Advice;public class Test {    /**     * 通知的前置和后置测试     */    public static void main(String[] args) {        //解析配置文件        ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");        Advice advice= (Advice)ctx.getBean("adviceimpl"); //自动代理beanname的方式        advice.fristMethod();        advice.secondMethod();    }}
复制代码

 

 

       2. 最原始的经典AOP

    2.1 最基本分层模式dao、biz、service以及最后测试Test

    2.1.1DAO层

复制代码
package cn.happy.dao;import cn.happy.entity.User;   //接口public interface UDao {    //保存方法    public void save(User user);} //实现类package cn.happy.dao;import cn.happy.entity.User;public class UserDaoImpl implements UDao{    public void save(User user) {        System.out.println("保存成功");    }}
复制代码

 

 

     2.1.2 BIZ层

复制代码
package cn.happy.biz;import cn.happy.entity.User;  //业务接口public interface UBiz {    //保存方法    public void save2(User user);}  //业务实现类package cn.happy.biz;import cn.happy.dao.UDao;import cn.happy.entity.User;public class UserBiz implements UBiz{    //dao的对象    private UDao udao;    public void save2(User user) {        udao.save(user);            }    public UDao getUdao() {        return udao;    }    public void setUdao(UDao udao) {        this.udao = udao;    }   }
复制代码

 

 

     2.1.3  AOP模块即service层

 

复制代码
package cn.happy.logger;import java.lang.reflect.Method;import org.springframework.aop.MethodBeforeAdvice;  //前置内容public class LoggerBefore implements MethodBeforeAdvice {    public void before(Method arg0, Object[] arg1, Object arg2)            throws Throwable {        System.out.println("save前置内容");       }}//后置内容package cn.happy.logger;import java.lang.reflect.Method;import org.springframework.aop.AfterReturningAdvice;public class LoggerAfter implements AfterReturningAdvice{    public void afterReturning(Object arg0, Method arg1, Object[] arg2,            Object arg3) throws Throwable {        System.out.println("save后置内容");       }}
复制代码

 

 

 

 

      2.1.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: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-4.1.xsd">        <!-- 业务biz与dao接口对象的实现 -->        <bean id="dao" class="cn.happy.dao.UserDaoImpl"></bean>        <bean id="biz" class="cn.happy.biz.UserBiz">            <property name="udao" ref="dao"></property>        </bean>         <!-- 前置与后置内容的配置 -->        <bean id="before" class="cn.happy.logger.LoggerBefore"></bean>        <bean id="after" class="cn.happy.logger.LoggerAfter"></bean>        <!-- aop的配置 -->        <aop:config>          <aop:pointcut expression="execution(public void save2(cn.happy.entity.User))" id="pointcut"/>          <!-- 在切入点处插入增强处理、完成"织入" -->          <aop:advisor advice-ref="before" pointcut-ref="pointcut"/>          <aop:advisor advice-ref="after" pointcut-ref="pointcut"/>        </aop:config></beans>       
复制代码

 

 

     2.1.5  测试类

复制代码
package cn.happy.test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import cn.happy.biz.UBiz;import cn.happy.entity.User;public class AOPTest {    public static void main(String[] args) {        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");        UBiz ubiz=(UBiz)context.getBean("biz");        User user=new User();        ubiz.save2(user);        System.out.println("save~ok");    }}
复制代码

 

 

       3. 然后就是Aspectj的注解以及xml配置文件的两种方式了。

     3.1 Aspectj注解

     3.1.1 接口和实现类

复制代码
package cn.happy.impl;//接口public interface AspectDao {          public void add();    public void delete();}//实现类package cn.happy.impl;public class AspectjIpml implements AspectDao{    //添加    public void add() {        System.out.println("==ADD==");    }    //删除    public void delete() {        System.out.println("==DELETE==");       }}
复制代码

 

      

      3.1.2 注解类Aspect

复制代码
package cn.happy.aspectj;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Before;@org.aspectj.lang.annotation.Aspectpublic class Aspect {    //前置增强     @Before(value="execution(public * *(..))")    public void asBefore(){        System.out.println("这是前置增强");    }   //后置增强     @AfterReturning(value="execution(public * *(..))")    public void asAfterReturning(){        System.out.println("这是后置增强");    }   //环绕增强     @Around(value="execution(public * *(..))")    public void asAround(ProceedingJoinPoint pj){         System.out.println("这是环绕前置增强");         try {            pj.proceed();        } catch (Throwable e) {            //抓捕异常            e.printStackTrace();        }        System.out.println("这是环绕后置增强");    }   //异常增强     @AfterThrowing(value="execution(public * *(..))")    public void asThorws(){        System.out.println("这是异常增强");    }   //最终增强     @After(value="execution(public * *(..))")    public void asAfter(){        System.out.println("这是最终增强");    }}
复制代码

 

 

     3.1.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"    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/context http://www.springframework.org/schema/context/spring-context.xsd        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">   <!-- 目标对象 -->   <bean id="aspectimpl" class="cn.happy.impl.AspectjIpml"></bean>   <!-- 增强类 -->   <bean id="aspectj" class="cn.happy.aspectj.Aspect"></bean>   <!-- 扫描整个项目 关联注解类和实现类 -->   <aop:aspectj-autoproxy /></beans>
复制代码

 

   

     3.1.4   测试类

复制代码
package cn.happy.test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import cn.happy.impl.AspectDao;public class AspectjTest {    /**     * 注解测试 */    public static void main(String[] args) {        // 解析配置文件        ApplicationContext ctx = new ClassPathXmlApplicationContext(                "applicationContext.xml");        AspectDao aspect = (AspectDao) ctx.getBean("aspectimpl");        aspect.add();        aspect.delete();    }}
复制代码

 

 

      4. Aspectj的XML配置法,其他的基本都一样只要修改Aspectj增强类和配置文件就行了

     4.1 Aspect增强类只需将那些注解消去即可

复制代码
package cn.happy.aspectj;import org.aspectj.lang.ProceedingJoinPoint;public class Aspect {    //前置增强    public void asBefore(){        System.out.println("这是前置增强");    }    //后置增强    public void asAfterReturning(){                System.out.println("这是后置增强");    }  //环绕增强    public void asAround(ProceedingJoinPoint pj){        System.out.println("这是环绕前置增强");        try {            pj.proceed();        } catch (Throwable e) {            //抓捕异常            e.printStackTrace();        }        System.out.println("这是环绕后置增强");    }  //异常增强    public void asThorws(){                System.out.println("这是异常增强");    }  //最终增强    public void asAfter(){                System.out.println("这是最终增强");    }}
复制代码

 

 

      4.2 XML的配置文件会稍微会复杂一点,但大致的还是跟对原始的经典aop实现方式相同

复制代码
<?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"    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/context http://www.springframework.org/schema/context/spring-context.xsd        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">   <!-- 目标对象 -->   <bean id="aspectimpl" class="cn.happy.impl.AspectjIpml"></bean>   <!-- 增强类 -->   <bean id="aspectj" class="cn.happy.aspectj.Aspect"></bean>   <!-- Aspectj的XML配置文件 -->   <aop:config>    <aop:pointcut expression="execution(public * *(..))" id="pointcut"/>    <aop:aspect ref="aspectj">     <aop:before method="asBefore" pointcut-ref="pointcut"/>     <aop:after-returning method="asAfterReturning" pointcut-ref="pointcut"/>     <aop:after-returning method="asAround(org.aspectj.lang.ProceedingJoinPoint)" pointcut-ref="pointcut"/>     </aop:aspect>   </aop:config></beans>
复制代码

 

      

      好了,这就是AOP(面向切面编程)的四种实现方式了。希望你们看了之后能让你们对AOP面向切面编程思想有更深的了解。

原创粉丝点击