标签:method png over 位置 encoding strong 使用 方式 XML
本随笔内容要点如下:
AOP(Aspect Oriented Programming),即面向切面编程。那什么是面向切面编程呢?切面又是什么呢?
如下图,本来存在ServiceA、ServiceB、ServiceC的,一刀把它们给切了。那这个面就是切面,切面切面,就是切开的面。
面向切面编程呢,就是在这个大切面上插入代码,使得ServiceA、ServiceB、ServiceC都能够实现插入的逻辑。在编码中,经常会在一个类中抽取公共代码形成一个独立的方法。而面向切面编程呢,则是抽取多个类中多个方法的相同代码形成一个独立的模块,而这些相同的代码就是横切关注点。例如事务,我们可能会在这些Service中的方法添加事务,而这些事务又与具体的业务逻辑无关,不属于Service的职责,那我们可以将它抽取出来形成一个类,在通过AOP编程来实现原本的逻辑。如下图:
对于织入,有一下几种形式:
Spring只支持运行期织入,AspectJ三种都支持
本随笔使用xml实现,下篇随笔再使用注解实现。
Spring中有两种方式来实现代理。第一种是Java自带的代理,它要求被代理类必须实现接口。第二种是使用了CGLib,即使被代理类没有实现接口也能被代理。除了引入基础的spring jar包之外,还需要引入aspectjweaver包。我使用的spring版本时4.3.2.RELEASE,当使用aspectjweaver1.8.9时会报错,降到1.8.6就可以正常使用了。
首先定义一个接口IService以及其实现类ServiceImpl
public interface IService { public void doSomething(int num); } public class ServiceImpl implements IService { @Override public void doSomething(int num) { System.out.println("doSomething --" + num); } }
把公共代码提取出来作为一个单独的模块即切面,那就需要定义一个切面,切面也是一个普通的bean,如下:
public class Aspect { public void before() { System.out.println("before"); } }
接着写配置文件
<?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.2.xsd "> <bean id="aspect" class="cn.powerfully.aspect.Aspect" /> <bean id="service" class="cn.powerfully.service.ServiceImpl" /> <aop:config> <aop:aspect ref="aspect"> <aop:pointcut expression="execution(* cn.powerfully.service.*.*(..))" id="p" /> <aop:before method="before" pointcut-ref="p" /> </aop:aspect> </aop:config> </beans>
首先先使用<bean>标签定义两个类,接着使用<aop:config>标签,关于切面的都要放在里面。
定义切面使用<aop:aspect>,切面呢,是由通知和切点组成的,所以定义通知和切点。<aop:before>用来定义一个前置通知,即在执行代码前执行。
除了前置通知,spring还提供了一下几种通知:
除了环绕通知外,其他通知的使用都类似前置通知。环绕通知的使用如下:
切面类中:
public Object around(ProceedingJoinPoint pjp) throws Throwable { long time = System.currentTimeMillis(); Object obj = null; obj = pjp.proceed(); System.out.println(System.currentTimeMillis() - time); return obj; }
该方法有类型ProceedingJoinPoint的参数,通过调用该对象中的proceed()方法可以继续执行被代理对象的逻辑代码。xml配置代码类似前置通知配置。
标签:method png over 位置 encoding strong 使用 方式 XML
原文地址:http://www.cnblogs.com/loading4/p/6327388.html