AOP的概述
- 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程
- AOP是一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构
- AOP最早由AOP联盟的组织提出的,制定了一套规范.Spring将AOP思想引入到框架中,必须遵守AOP联盟的规范
- 通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术
- AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型
- 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率
AOP的底层实现
Srping框架的AOP技术底层也是采用的代理技术,代理的方式提供了JDK的动态代理和CGLIB动态代理
JDK的动态代理
使用Proxy类来生成代理对象的代码如下
编写一个接口
public interface UserService {
public void save();
public void update();
public void select();
}
编写实现类(需要被代理的类)
public class UserServiceImpl implements UserService {
public void save() {
System.out.println("保存用户");
}
public void update() {
System.out.println("修改用户");
}
public void select() {
System.out.println("查询数据");
}
}
编写代理类,实现代理逻辑
public class ProxyUtils {
public static UserService getProxy(final UserService service){
UserService userService= (UserService) Proxy.newProxyInstance(service.getClass().getClassLoader(), service.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//编写代理逻辑
if(method.getName().equals("save")||method.getName().equals("update"))
System.out.println("开启事务...");
return method.invoke(service,args);//让被代理对象的方法正常执行
}
});
return userService;
}
}
编写测试方法
@Test
public void testProxyTest(){
UserService userService= (UserService) ProxyUtils.getProxy(new UserServiceImpl());
userService.save();
userService.update();
userService.select();
}
以上是JDK动态代理具体实现方式,这种方法必须提供需要代理对象的接口
CGLIB的动态代理
spring提供了一种代理技术,不需要接口也能实现动态代理,下面来看看CGLIB的具体实现方法
引入spring的core包,里面就有CGLIB,我这里引入了context里面包含了core
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.4.RELEASE</version>
</dependency>
被代理对象还是使用UserServiceImpl,下面编写代理对象
public class CGLIBUtils {
public static UserServiceImpl getProxy(){
// 创建CGLIB核心的类
Enhancer enhancer = new Enhancer();
// 设置父类
enhancer.setSuperclass(UserServiceImpl.class);
// 设置回调函数
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
if("save".equals(method.getName())||"update".equals(method.getName())){
// 开启事务
System.out.println("开启事务...");
}
return methodProxy.invokeSuper(obj, args);
}
});
// 生成代理对象
UserServiceImpl proxy = (UserServiceImpl) enhancer.create();
return proxy;
}
}
编写测试代码
@Test
public void testCGLIB(){
UserService userService= (UserService) CGLIBUtils.getProxy();
userService.save();
userService.update();
userService.select();
}
说明,CGLIB是通过生成子类的的方式,来实现代理,所以不需要接口也能实现