什么是AOP
1,面向切面编程Aspect-Oriented-Programming(动态代理的实现机制)
是对面向对象的思维方式的有力补充,正常的程序就好像是一条线,而AOP则是在这 条线上的某一点加上一些逻辑。
2,好处:可以动态的添加和删除在切面上的逻辑而不影响原来的执行代码
- Filter
- Struts2的interceptor 这两个都是面向切面的
3,概念:
- JoinPoint 释意:切面与原方法交接点 即 切入点(哪个方法前要加入一些逻辑)
- PointCut 释意:切入点集合
- Aspect(切面)释意:可理解为代理类前说明
- Advice 释意:可理解为代理方法前说明 例如@Before
- Target 释意:被代理对象 被织入对象
- Weave 释意:织入
4,annotation初步
aspectj:面向aop编程的框架,可以产生动态代理,spring使用了它。
<?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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <context:annotation-config /> <context:component-scan base-package="com.bjsxt"/> <aop:aspectj-autoproxy /> </beans>
织入点语法:execution(public void com.bjsxt.dao.impl.UserDAOImpl.save(com.bjsxt.model.User))
@Aspect @Component public class LogInterceptor { @Before("execution(public void com.bjsxt.dao.impl.UserDAOImpl.save(com.bjsxt.model.User))")//声明把before方法发在那个方法前 public void before(){ System.out.println("hha"); } }
Spring AOP配置与应用
1,两种方式:
- 使用Annotation
- 使用xml
2,Annotation
- 加上对应的xsd文件spring-aop.xsd
- beans.xml <aop:aspectj-autoproxy />
- 此时就可以解析对应的Annotation了
- 建立我们的拦截类
- 用@Aspect注解这个类
- 建立处理方法
- 用@Before来注解方法
- 写明白切入点(execution …….)
- 让spring对我们的拦截器类进行管理@Component
3,常见的Annotation:
- @Pointcut 切入点声明 以供其他方法使用 , 例子如下:
@Aspect @Component public class LogInterceptor { @Pointcut("execution(public * com.bjsxt.dao..*.*(..))") public void myMethod(){} @Around("myMethod()") public void before(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("method before"); pjp.proceed(); } @AfterReturning("myMethod()") public void afterReturning() throws Throwable{ System.out.println("method afterReturning"); } @After("myMethod()") public void afterFinily() throws Throwable{ System.out.println("method end"); } }
- @Before 发放执行之前织入
- @AfterReturning 方法正常执行完返回之后织入(无异常)
- @AfterThrowing 方法抛出异常后织入
- @After 类似异常的finally
- @Around 环绕 类似filter , 如需继续往下执行则需要像filter中执行FilterChain.doFilter(..)对象一样 执行 ProceedingJoinPoint.proceed()方可,例子如下:
@Around("execution(* com.bjsxt.dao..*.*(..))") public void before(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("method start"); pjp.proceed();//类似FilterChain.doFilter(..)告诉jvm继续向下执行 }
4,织入点语法
- void !void
- 参考文档(* ..)
如果 execution(* com.bjsxt.dao..*.*(..))中声明的方法不是接口实现 则无法使用AOP实现动态代理,此时可引入包” cglib-nodep-2.1_3.jar” 后有spring自动将普通类在jvm中编译为接口实现类,从而打到可正常使用AOP的目的.
5,xml配置aop(重要)
//@Aspect //@Component public class LogInterceptor { //@Pointcut("execution(public * com.bjsxt.service..*.add(..))") public void myMethod(){}; //@Before("myMethod()") public void before() { System.out.println("method before"); } //@Around("myMethod()") public void aroundMethod(ProceedingJoinPoint pjp) throws Throwable { System.out.println("method around start"); pjp.proceed(); System.out.println("method around end"); } }
<?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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd" > <context:annotation-config /> <context:component-scan base-package="com.bjsxt"/> <bean id="logInterceptor" class="com.bjsxt.aop.LogInterceptor"></bean> <aop:config> <aop:pointcut expression="execution(public * com.bjsxt.service..*.add(..))" id="servicePointCut"/> <aop:aspect id="logAspect" ref="logInterceptor"> <!-- <aop:before method="before" pointcut="execution(public * com.bjsxt.service..*.add(..))" /> --> <aop:before method="before" pointcut-ref="servicePointCut" /> </aop:aspect> </aop:config> </beans>