Spring Aop学习
首先AOP是OOP的一种补充
Spring实现AOP有两种方式
1.使用注解
2.配置XML
一、使用注解
先搞好需要注入的方法
package com.zhyonk.serviceImpl; import com.zhyonk.service.PersonService; public class PersonServiceImpl implements PersonService{ @Override public void save(String name) { System.out.println("我是save方法"); } @Override public void update(String name, Integer id) { System.out.println("我是update()方法"); } @Override public String getPersonName(Integer id) { System.out.println("我是getPersonName()方法"); return "xxx"; } }
接下来搞一个切面类
package com.zhyonk.aspect; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; public class MyAspect { public void before(JoinPoint point){ String name = point.getTarget().getClass().getName(); System.out.println("注入"+name+"方法"+"...前置通知"); } public void afterReturn(){ System.out.println("方法结束了。。。后置通知"); } public void after(){ System.out.println("不管方法有没有执行完。一定会执行的方法...最终通知"); } public void afterThrowing(){ System.out.println("方法执行时发生异常。。。执行异常通知"); } public Object Around(ProceedingJoinPoint point) throws Throwable{ Object obj = null; System.out.println("进入Around通知"); try { obj = point.proceed(); //在这里获得需要切入的对象,将要切入的对象用ASM框架进行字节码重新编译 System.out.println("退出Around通知"); } catch (Throwable e) { this.afterThrowing(); //相当于异常抛出后通知 throw e; }finally{ System.out.println("Around中一定会执行的方法"); } return obj; //返回编译之后的字节码生成的对象 } }
然后在xml中进行配置
<bean id="personServiceImpl" class="com.zhyonk.serviceImpl.PersonServiceImpl" /> <bean id="myAspectBean" class="com.zhyonk.aspect.MyAspect"/> <aop:config> <aop:aspect id="myAspect" ref="myAspectBean"> <aop:pointcut expression="execution(* com.zhyonk.serviceImpl.PersonServiceImpl.*(..))" id="anyMethod"/> <aop:before method="before" pointcut-ref="anyMethod"/> <aop:after method="after" pointcut-ref="anyMethod"/> <aop:after-throwing method="afterThrowing" pointcut-ref="anyMethod"/> <aop:after-returning method="afterReturn" pointcut-ref="anyMethod"/> <aop:around method="Around" pointcut-ref="anyMethod"/> </aop:aspect> </aop:config>
哦了
运行结果
1 INFO : org.springframework.context.support.FileSystemXmlApplicationContext - Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@536c73aa: startup date [Fri Dec 23 09:24:30 GMT+08:00 2016]; root of context hierarchy 2 INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from file [C:\dev\workspace\Eclipseworkspace\Spring\src\main\webapp\WEB-INF\spring\root-context.xml] 3 INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@48d3b591: defining beans [org.springframework.aop.config.internalAutoProxyCreator,personServiceImpl,myAspectBean,org.springframework.aop.aspectj.AspectJPointcutAdvisor#0,org.springframework.aop.aspectj.AspectJPointcutAdvisor#1,org.springframework.aop.aspectj.AspectJPointcutAdvisor#2,org.springframework.aop.aspectj.AspectJPointcutAdvisor#3,org.springframework.aop.aspectj.AspectJPointcutAdvisor#4,anyMethod]; root of factory hierarchy 4 注入com.zhyonk.serviceImpl.PersonServiceImpl方法...前置通知 5 进入Around通知 6 我是save方法 7 不管方法有没有执行完。一定会执行的方法...最终通知 8 方法结束了。。。后置通知 9 退出Around通知 10 Around中一定会执行的方法
总结一下,用xml文件配置的话比较繁琐。需要将注入的方法声明在xml<aop:config>中,先搞一个<aop:poincut/>在讲需要的方法befoe、after之类的写进去
再看一下执行结果。
before>around>Method(要注入的方法)>after-return>after
在看一下用Annotation进行注入
还是用之前的那个需要注入的类
搞一个注入类,在类中进行声明
package com.zhyonk.interceptor; 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.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; @Aspect public class MyInterceptor { @Pointcut("execution(* com.zhyonk.serviceImpl.PersonServiceImpl.*(..))") private void anyMethod(){}//定义一个切入点 @Before("anyMethod() && args(name)") public void doAccessCheck(String name) { System.out.println(name); System.out.println("前置通知"); } @AfterReturning("anyMethod()") public void doAfter() { System.out.println("后置通知"); } @After("anyMethod()") public void after() { System.out.println("最终通知"); } @AfterThrowing("anyMethod()") public void doAfterThrow() { System.out.println("例外通知"); } @Around("anyMethod()") public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable { System.out.println("进入环绕通知"); Object object = pjp.proceed();// 执行该方法 System.out.println("退出方法"); return object; } }
然后在xml的IOC容器中加入Bean

运行结果
1 INFO : org.springframework.context.support.FileSystemXmlApplicationContext - Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@751dc8af: startup date [Fri Dec 23 09:40:38 GMT+08:00 2016]; root of context hierarchy 2 INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from file [C:\dev\workspace\Eclipseworkspace\Spring\src\main\webapp\WEB-INF\spring\root-context.xml] 3 INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5fe633e4: defining beans [org.springframework.aop.config.internalAutoProxyCreator,myInterceptor,personServiceImpl,myAspectBean]; root of factory hierarchy 4 进入环绕通知 5 .... 6 前置通知 7 我是save方法 8 最终通知 9 退出方法 10 后置通知
结果和上面一样。。
很简单的感觉。
接下来我要自己实现一个AOP框架!`(*∩_∩*)′

浙公网安备 33010602011771号