zoukankan      html  css  js  c++  java
  • 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.Aspect
    public 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面向切面编程思想有更深的了解。

  • 相关阅读:
    ios UIWebView截获html并修改便签内容(转载)
    IOS获取系统时间 NSDate
    ios 把毫秒值转换成日期 NSDate
    iOS  如何判断当前网络连接状态  网络是否正常  网络是否可用
    IOS开发 xcode报错之has been modified since the precompiled header was built
    iOS系统下 的手机屏幕尺寸 分辨率 及系统版本 总结
    iOS 切图使用 分辨率 使用 相关总结
    整合最优雅SSM框架:SpringMVC + Spring + MyBatis 基础
    Java面试之PO,VO,TO,QO,BO
    Notes模板说明
  • 原文地址:https://www.cnblogs.com/bdpsc/p/5955494.html
Copyright © 2011-2022 走看看