欢迎转载交流,博客地址http://www.cnblogs.com/shizhongtao/p/3469776.html
首先,什么是aop,其实通俗一点讲就是,再方法执行时候我们加入其它业务逻辑。比如正常的执行顺序我们可以比作一条线,而aop就是在这个线上加上两刀,在断点 处加入新的东西。spring的aop实现借助了j2se的动态代理(dynamic proxies)来实习,具体java接口是InvocationHandler。因为java的动态代理是基于接口来实现的;而有些时候,我们的被代理类不一定实现了接口,这时候就需要CJLIB这个代理来实现,所以spring在aop时候需要引入CJLIB这个jar包,好在spring3.2以后,把这个jar集成到自身的框架中去了,不需要用户再去引入了。另外,spring aop用了aspect这个代理框架,所以在使用aop时候,我们要加入aspectjweaver.jar(如果是spring3的话,aspectjweaver需要1.68以后的版本)。
为了使用aop我们在spring的配置文件中要加入下面这个元素。schema的话,可以参看官方文档。
<aop:aspectj-autoproxy/>
注:如果你不论哪种情况都希望使用CGLIB代理来配置切面服务,你这样写就可以了”
<aop:aspectj-autoproxy proxy-target-class="true"/>
如果只是想某个aop使用,就在那个aop的配置中加入这一属性:
<aop:config proxy-target-class="true"> <!-- other beans defined here... --> </aop:config>
首先,我们定义Manager类,模仿mvc中的service层。
1 package com.bing.test; 2 3 import org.springframework.stereotype.Component; 4 5 @Component("manager") 6 public class Manager { 7 private String myName="bingyulei"; 8 private String description="nothing to say"; 9 10 public void sayHello() { 11 System.out.println("Hello " + myName); 12 } 13 14 public void getDes() { 15 System.out.println(description); 16 17 } 18 }
假如我想在sayHello方法前假如自己的业务逻辑我该如何做,简单示例如下:
这样你就可以声明一个切面类,来进行测试,这里我用annotation的方式,切面类NotVeryUsefulAspect。
1 package com.bing.test; 2 3 import org.aspectj.lang.annotation.AfterReturning; 4 import org.aspectj.lang.annotation.Aspect; 5 import org.aspectj.lang.annotation.Before; 6 import org.aspectj.lang.annotation.Pointcut; 7 import org.springframework.stereotype.Component; 8 9 @Aspect 10 // 定义切面类 11 @Component 12 // 把类装载到容器,与@service等作用一样 13 public class NotVeryUsefulAspect { 14 15 /* @Pointcut("execution(public * com.bing.test..*.sayHello(..))") 16 public void inManager() {} 17 @Pointcut("within(com.bing.test..*)") 18 public void excutionManager() {}*/ 19 // 表示在方法前面执行 20 @Before("execution(public * com.bing.test.*.sayHello(..))") 21 public void before() { 22 23 System.out.println("before Method"); 24 } 25 @AfterReturning("execution(public * com.bing.test..*.sayHello(..))") 26 public void after() { 27 28 System.out.println("after Method"); 29 } 30 }
然后我们用junit测试一下:
package com.bing.jtest; import javax.annotation.Resource; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.bing.test.Manager; @ContextConfiguration(locations = { "classpath:applicationContext.xml" }) @RunWith(SpringJUnit4ClassRunner.class) public class Testr { @Resource(name="manager") private Manager manager; @Test public void test() { manager.sayHello(); //manager.getDes(); } }
得到结果:
before Method
Hello bingyulei
如果用xml的配置方式,可以这样配置
1 <bean id="myInterceptor" class="com.bing.test.NotVeryUsefulAspect"></bean> 2 3 <aop:config> 4 <aop:aspect id="myAspect" ref="myInterceptor"> 5 <aop:before method="before" 6 pointcut="execution(public * com.bing..*.sayHello(..))" /> 7 <!-- 第一个*表示任何返回类型,“..”表示这个包下的所有子包,第二个*代表所有类,第二个“..”匹配了一个接受任意数量参数 --> 8 <!-- 当然sayHello方法你也可以用*代替,这样就表示所有方法。 --> 9 </aop:aspect> 10 </aop:config>