AOP(AspectOriented Programming,面向切面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善,是软件开发中的一个热点,也是Spring框架中的一个重要内容。AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任,例如事务处理、日志管理、权限控制等,封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。
1、Aspect:对横切关注点模块化;
2、Advice:对横切性关注点的具体实现,包括调用目标之前执行(Before Advice)、调用目标之后执行(After Advice)、抛出异常(Throw Advice);
3、Pointcut:横切性关注点的应用范围,它定义了Advice应用到哪些JoinPoint上;应用范围,第一个* 表示所有的有无返回值,第二个*表示有无参数,代表匹配所有情况;
4、JoinPoint:连接点,调用目标方法的地方。在AOP中表示“在哪里做”;
5、Weave:织入,将Advice应用到TargetObject上的过程;
6、Introduction:引入,可以动态地为类添加方法,对类的增强叫做引入(Introduction),对方法的增强叫做织入(Weaving)。
本Demo实现了在调用方法之前检查安全性。
不变的代码:
<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.jmj.spring;
/**
* ClassName: UserManager
* @Description: 接口
* @author meng
* @date 2016-5-6 上午10:51:44
*/
public interface UserManager {
public void addUser(String username, String password);
public void delUser(int userId);
}
</span><span style="font-family:KaiTi_GB2312;font-size:18px;">package com.jmj.spring;
/**
* ClassName: UserManagerImpl
* @Description: 具体实现类
* @author meng
* @date 2016-5-6 上午10:51:24
*/
public class UserManagerImpl implements UserManager {
public void addUser(String username, String password) {
//checkSecurity();
System.out.println("---------UserManagerImpl.add()--------");
}
public void delUser(int userId) {
//checkSecurity();
System.out.println("---------UserManagerImpl.delUser()--------");
}
}
</span><span style="font-family:KaiTi_GB2312;font-size:18px;">package com.jmj.spring;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* ClassName: Client
* @Description: 客户端
* @author meng
* @date 2016-5-6 上午10:52:05
*/
public class Client {
public static void main(String[] args){
//读取配置文件
BeanFactory factory =new ClassPathXmlApplicationContext("applicationContext.xml");
UserManager userManager=(UserManager)factory.getBean("userManager");
userManager.addUser("张三", "123");
}
}
</span>重要部分:
1、 在横切类中添加注解
<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.jmj.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;
//将横切性关注点模块化
//使用注解方式:Annotation
@Aspect
public class SecurityHandler {
//定义检查安全性在调用添加方法之前
/**
* 定义Advice,表示Advice应用到那些PointCut订阅的JoinPoint上
*/
//对横切性关注点的具体实现
@Before("addAddMethod()") //前置增强
//@After("addAddMethod()") //后置增强
private void checkSecurity() {
System.out.println("-------checkSecurity-------");
}
/**
* 定义PointCut,PointCut的名称为addAddMethod(),此方法没有返回值和参数
* 该方法是一个标识,不进行调用
*/
//横切性关注点的应用范围
//应用范围 ,第一个* 表示所有的有无返回值,第二个*表示有无参数,代表匹配所有情况
@Pointcut("execution(* add*(..))")
private void addAddMethod(){};
}
</span>
2、 在配置文件(applicationContext.xml)中,启用AspectJ对Annotation的支持
<span style="font-family:KaiTi_GB2312;font-size:18px;"><!--启用AspectJ对Annotation的支持 -->
<aop:aspectj-autoproxy/>
<bean id="userManager" class="com.jmj.spring.UserManagerImpl"/>
<bean id="securityHandler" class="com.jmj.spring.SecurityHandler"/></span>
1、横切类
<span style="font-family:KaiTi_GB2312;font-size:18px;">public class SecurityHandler {
private void checkSecurity() {
System.out.println("-------checkSecurity-------");
}
}</span> 此类中,只需要切入方法的具体实现,而不需要管如何切入,何时切入?
2、在配置文件(applicationContext.xml)中,管理具体的切入形式
<span style="font-family:KaiTi_GB2312;font-size:18px;"> <bean id="userManager" class="com.jmj.spring.UserManagerImpl"/>
<bean id="securityHandler" class="com.jmj.spring.SecurityHandler"/>
<aop:config>
<!--相当于注解中的aspect ,对横切关注点的模块化 -->
<aop:aspect id="securityAspect" ref="securityHandler">
<!--定义了Advice应用到哪些JoinPoint上,对Spring来说是方法调用 -->
<!--以add开头的方法 -->
<!-- <aop:pointcut id="addAddMethod" expression="execution(* add*(..))"/> -->
<!--可以使用引用包,范围是:com.jmj.spring这个包下的所有类的所有方法 -->
<!-- <aop:pointcut id="addAddMethod" expression="execution(* com.jmj.spring.*.*(..))"/> -->
<!--只对添加和删除起作用,对以add和del开头的方法起作用 -->
<aop:pointcut id="addAddMethod" expression="execution(* com.jmj.spring.*.add*(..)) || execution(* com.jmj.spring.*.del*(..))"/>
<!--对横切关注点的具体实现 -->
<aop:before method="checkSecurity" pointcut-ref="addAddMethod"/>
<!-- <aop:after method="checkSecurity" pointcut-ref="addAddMethod"/> -->
</aop:aspect>
</aop:config></span>
AOP和OOP的关系,如图所示:
AOP的优点:低耦合,高扩展。
原文:http://blog.csdn.net/shiqijiamengjie/article/details/51318358