面向切面编程,通过提供另外一种思考程序结构的途经来弥补面向对象编程的不足。
面向对象中模块化的单位是classes;AOP中模块化的单位是切面。AOP框架是spring的一个重要组成部分。
一:Annotation方式完成AOP:
package com.lf.zym.spring; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; @Aspect public class SecurityHandler{ //定义Pointcut,Pointcut的名称为addAddMethod(),此方法没有返回值和参数 @Pointcut("execution(* add*(..))") private void addAddMethod(){}; //定义Advice,表示我们的Advice应用到哪些Pointcut订阅的Joinpoint上 @Before("addAddMethod()") private void checkSecurity(){ System.out.println("---------------checkSecurity()--------------"); } }
<?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" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <!-- 启用AspectJ对Annotation的支持 --> <aop:aspectj-autoproxy/> <bean id="userManager" class="com.lf.zym.spring.UserManagerImpl"/> <bean id="securityHandler" class="com.lf.zym.spring.SecurityHandler"/> </beans>
客户端代码:
package com.lf.zym.spring; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Client { public static void main(String[] args) { BeanFactory factory=new ClassPathXmlApplicationContext("applicationContext.xml"); UserManager userManager=(UserManager)factory.getBean("userManager"); userManager.addUser("赵亚盟","1"); } }执行addAddMethod()方法之前先执行checkSecurity()方法,如果是注解写的是after,则在addAddMethod()方法之后执行结果如下:
二:采用静态配置文件的方式完成AOP,上面SecurityHandler中的注解就都不需要了
public class SecurityHandler{ private void checkSecurity(){ System.out.println("---------------checkSecurity()--------------"); } }配置文件中进行AOP的配置:
<bean id="userManager" class="com.lf.zym.spring.UserManagerImpl"/> <bean id="securityHandler" class="com.lf.zym.spring.SecurityHandler"/> <aop:config> <aop:aspect id="securityAspect" ref="securityHandler"> <aop:pointcut id="addAddMethod" expression="execution(* com.lf.zym.spring.*.add*(..)) || execution(* com.lf.zym.spring.*.del*(..)) "/> <aop:before method="checkSecurity" pointcut-ref="addAddMethod"/> </aop:aspect> </aop:config>
调用add或者del方法之前会先执行checkSecurity的方法,执行其他的方法不会调用checkSecurity方法。
package com.lf.zym.spring; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Client { public static void main(String[] args) { BeanFactory factory=new ClassPathXmlApplicationContext("applicationContext.xml"); UserManager userManager=(UserManager)factory.getBean("userManager"); userManager.addUser("张三","1"); } }
执行结果:
如果调用的不是add或者del,则不会调用checkSecurity方法。
例如客户端执行的是find方法:
String username=userManager.findUserById(1); System.out.println(username);
将客户端调用信息传递到Advice中:可以采用Adice中添加一个JoinPoint参数。
public class SecurityHandler{ private void checkSecurity(JoinPoint joinPoint){ for(int i=0;i<joinPoint.getArgs().length;i++){ System.out.println(joinPoint.getArgs()[i]); } System.out.println("---------------checkSecurity()--------------"); } }
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
小结:
AOP首先是一种思想,为了更好的降低业务逻辑之间的耦合性,具体概念性的理解可以看之前总结的一篇博客。
博客链接:点击打开链接