你的位置:首页 > Java教程

[Java教程]spring AOP四种实现方式


1. 经典的基于代理的AOP 

  1. 创建通知:定义一个接口

 

public interface Sleepable{   void sleep(); }然后写一个Human类,他实现了这个接口public Human implements Sleepable{   public void sleep(){   System.out.println("睡觉中...!");  }}

2.编写一个SleepHelper类,它里面包含了睡觉的辅助工作,用AOP术语来说它就应该是通知

public class SleepHelper implements MethodBeforeAdvice,AfterReturningAdvice {  public void before(Method method, Object[] arguments, Object target)      throws Throwable {    System.out.println("睡觉前");      }  public void afterReturning(Object rturnValue, Method method, Object[] arguments,      Object target) throws Throwable {    System.out.println("睡觉后");      }}

然后在spring配置文件中进行配置:

<!-- 被代理目标对象 -->

<bean id="Human" class="cn.happy.dao.Human"></bean><bean id="SleepHelper" class="cn.happy.aop.SleepHelper"></bean>//定义切点的常用的两种方式:1)使用正则表达式 2)使用AspectJ表达式,//这里用正则表达式<!-- 顾问 -->   <bean id="BeforAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">       <property name="advice" ref="BeforAdvice"></property>    <property name="pattern" value=".*l.*g.*"></property>    </bean><!-- 代理对象 -->// ProxyFactoryBean是一个代理,我们可以把它转换为//proxyInterfaces中指定的实现该interface的代理对象   <bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">       <property name="target" ref="Human"></property>    <property name="interceptorNames" value="BeforAdvisor"></property>    </bean>

代理类

public class StuTest {  public static void main(String[] args) {    //通过ClassPath    ApplicationContext context=new ClassPath);    //通过ApplicationContext的getBean()方法,根据id来获取Bean的实例    Sleepable s=(Sleepable)context.getBean("Human");    s.sleep();  }}

3、使用AspectJ的注解

用@Aspect的注解来标识切面

@Aspect//该类为切面public class MyAspect {  @Before(value="execution(public * *(..))") public void mybefore(){       System.out.println("前置增强"); }  //后置增强  @AfterReturning(value="execution(public * *(..))")   public void myafterReturning(){           System.out.println("后置增强");   }    //异常增强    @AfterThrowing(value="execution(public * *(..))")     public void myafterThrowing(){               System.out.println("异常增强");     }        //环绕增强    @Around(value="execution(public * *(..))")     public void myAround(ProceedingJoinPoint jp){      System.out.println("环绕前增强");         try {          jp.proceed();        } catch (Throwable e) {          // TODO Auto-generated catch block          e.printStackTrace();        }         System.out.println("环绕后增强");             }        //最终增强        @After(value="execution(public * *(..))")         public void myafterLogger(){                       System.out.println("最终增强");         }}

Spring配置文件:

<!-- 目标对象 -->  <bean id="Human" class="cn.happy.dao.IserviceImpl"></bean>  <!-- 切面: -->  <bean id="myAspect" class="cn.happy.aop.MyAspect"></bean>   <aop:aspectj-autoproxy/>

测试类

public class StuTest {  public static void main(String[] args) {    ApplicationContext context=new ClassPath);    Sleepable s=(Sleepable)context.getBean("Service");    s.sleep();  }}

4、通过<aop:config>来配置(纯POJO切面)

<aop:advisor> 定义一个AOP通知者
<aop:after> 后通知
<aop:after-returning> 返回后通知
<aop:after-throwing> 抛出后通知
<aop:around> 周围通知
<aop:aspect>定义一个切面
<aop:before>前通知
<aop:config>顶级配置元素,类似于<beans>这种东西
<aop:pointcut>定义一个切点

public class MyAspect { public void mybefore(){       System.out.println("前置增强"); } public String myafterReturning(String Returning){       System.out.println("前置增强");    return Returning;}}

public class IserviceImpl implements Iservice{  public void log() {    System.out.println("开启事务");      }  public String dofirst() {    System.out.println("记录日志");    return "";      }  }

Spring的配置文件:

<!-- 目标对象 -->  <bean id="Service" class="cn.happy.dao.IserviceImpl"></bean>  <!-- 切面: -->  <bean id="myAspect" class="cn.happy.aop.MyAspect"></bean>  <!-- 配置切面 -->  <aop:config>  <!-- 配置切入点 -->    <aop:pointcut id="pointcut" expression="execution(public * *..Iservice.log(..))"/>    <!-- 将类方法定义为最终增强并引用pointcut切入点-->    <aop:aspect ref="myAspect">      <aop:after method="myafterReturning" pointcut-ref="pointcut"/>    </aop:aspect>  </aop:config>

测试类

public class SpringTest {  public static void main(String[] args) {     ApplicationContext context=new ClassPath);     Iservice bean = (Iservice)context.getBean("Service");    bean.log();    String count=bean.dofirst();     System.out.println(count);  }}