AOP简介
- 在软件开发行业,AOP 为
Aspect Oriented Programming
的缩写,意为:面向切面编程
- 通过
预编译
的方式和运行期间,使用动态代理的方式来实现程序功能的统一维护的一种技术 - AOP 是
OOP
(面向对象)的延续,是软件开发中的一个热点,也是 Spring 框架中的一个重要内容,是函数式
编程的一种衍生范型 - 利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑的各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率
开发中存在的问题
- 假如你需要在某一个功能之前加一个功能
- 你自己定义一个方法,然后在显示的手动调用
- 每个方法都要的话不都需要写一次
- 采用
纵向继承
的方式来进行改进
- AOP采用了
横向抽取
的机制取代了传统的纵向继承
- 不破坏原有的类,生成一个新的代理类,在原来类的基础上进行增强
- 可以随时添加,随时取消添加的功能
JDK动态代理
- 新建一个
GoodsDao
接口- 定义一个
save
接口规范代码如下:
/**
* @author: BNTang
**/
public interface GoodsDao {
void save();
}
- 创建一个实现类
GoodsDaoImpl
实现GoodsDao
接口- 并且实现当中的
save
方法,代码如下:
/**
* @author: BNTang
**/
public class GoodsDaoImpl implements GoodsDao {
public void save() {
System.out.println("save goods");
}
}
- 新建一个JDK代理类
JDKProxy
- 在当中定义一个
createProxy
方法,代码如下:
/**
* @author: BNTang
**/
public class JDKProxy {
private GoodsDao goodsDao;
public JDKProxy(GoodsDao goodsDao) {
this.goodsDao = goodsDao;
}
public GoodsDao createProxy() {
GoodsDao goodsDaoProxy = (GoodsDao) Proxy.newProxyInstance(goodsDao.getClass().getClassLoader(),
goodsDao.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("save".equals(method.getName())) {
System.out.println("permission check");
return method.invoke(goodsDao, args);
}
return method.invoke(goodsDao, args);
}
});
return goodsDaoProxy;
}
}
- 测试类代码如下:
/**
* @author: BNTang
**/
public class GoodsDaoTest {
public void Demo() {
GoodsDao goodsDao = new GoodsDaoImpl();
JDKProxy jdkProxy = new JDKProxy(goodsDao);
GoodsDao proxyBean = jdkProxy.createProxy();
proxyBean.save();
}
}
- 输出结果如下:
permission check
save goods
CgLib动态代理
- CgLib 是一个第三方开源的第三方库
- 可以动态的添加类的属性和方法
- 在 Spring 的核心包当中已经引入了
cglib
- CgLib 采用的是
继承的方式
来创建的代理对象- 创建
CgLibProxy
类,代码如下:
/**
* @author: BNTang
**/
public class CgLibProxy {
private GoodsDao goodsDao;
public CgLibProxy(GoodsDao goodsDao) {
this.goodsDao = goodsDao;
}
public GoodsDao createProxy() {
// 1.创建 CgLib 核心类
Enhancer enhancer = new Enhancer();
// 2.采用的是继承的方式来创建的代理对象
enhancer.setSuperclass(goodsDao.getClass());
// 3.设置回调方法
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if ("save".equals(method.getName())) {
System.out.println("permission check");
return methodProxy.invokeSuper(proxy, args);
}
return methodProxy.invokeSuper(proxy, args);
}
});
// 4.创建代理对象
return (GoodsDao) enhancer.create();
}
}
- 测试类代码如下:
/**
* @author: BNTang
**/
public class GoodsDaoTest {
public void Demo() {
GoodsDao goodsDao = new GoodsDaoImpl();
CgLibProxy cgLibProxy = new CgLibProxy(goodsDao);
GoodsDao proxy = cgLibProxy.createProxy();
proxy.save();
}
}
Spring的AOP简介
- AOP 的思想,最早是由AOP联盟组织提出的
- 使用这种思想最好的框架是
Spring
AspectJ
- Spring 的 AOP有自己的实现方式
- 但是自己实现的方式非常的繁琐
- AspectJ 是一个
AOP框架
- Spring 放弃了自己传统的方式,也就是自己实现的方式
- 引入
AspectJ
作为自身的 AOP来进行开发