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面向切面编程思想有更深的了解。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM