SpringAOP 基础学习
一、SpringAOP概念的介绍
AOP是一种面向切面编程的规范,不是Spring特有的,SpringAOP只是使用使用了AOP的规范,利用SpringAOP完成声明式的事物的控制
事物、权限、日志:横切性的关注点,这些关注点和业务关系不大,但是必须存在,遍布在项目的各个角落,这些需要使用AOP进行统一管理
二、静态代理
静态代理不属于spring
-
代理方和被代理方都需要实现同一个接口
-
代理方中必须要有被代理方的引用
案例:二手车买卖平台代理用户买车
接口:
public interface Service { void buyCar(); }
用户类:
public class Customer implements Service { @Override public void buyCar() { System.out.println("用户买车"); } }
二手车平台:
public class Company implements Service{ private Customer customer; public Company(Customer customer){ this.customer = customer; } @Override public void buyCar() { customer.buyCar(); } }
测试类:
public class Test { public static void main(String[] args) { Company company = new Company(new Customer()); company.buyCar(); } }
三、动态代理
动态代理:可以代理接口和类,动态代理类实现 InvocationHandler
接口
案例:某电脑销售公司,总公司不直接销售电脑,将订单需要的电脑让对应的城市的销售分公司出货
实现要求:1、分公司出货前都需要进行权限校验
2、调用代理的类对象,可以执行到对应分公司的销售方法
接口:(总公司 北京)
public interface BeiJing {
void sale(String brand);
}
实现类:(分公司成都)
/**
* @author Object(object_hui@sina.com)
* @description 成都分销商
* @date 2020/12/21
*/
public class ChengDu implements BeiJing{
@Override
public void sale(String brand) {
System.out.println("成都分公司销售"+brand+"电脑。");
}
}
实现类: (分公司 合肥)
/**
* @author Object(object_hui@sina.com)
* @description 合肥分销商
* @date 2020/12/21
*/
public class HeFei implements BeiJing{
@Override
public void sale(String brand) {
System.out.println("合肥分公司销售"+brand+"电脑。");
}
}
权限校验类:
/**
* @author Object(object_hui@sina.com)
* @description 权限校验
* @date 2020/12/21
*/
public class Security {
public static void security(){
System.out.println("权限校验");
}
}
动态代理类:(核心类)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @author Object(object_hui@sina.com)
* @description 动态代理类
* @date 2020/12/21
*/
public class DynamicProxy implements InvocationHandler {
//代理目标
private Object target;
//获取代理对象
public DynamicProxy(Object target){
this.target = target;
}
//获取代理类信息
public Object getProxyInstace(){
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
//核心方法,调用代理对象方法之前会执行该方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Security.security();
Object result = method.invoke(target, args);
return result;
}
}
测试类:
/**
* @author Object(object_hui@sina.com)
* @description 测试类
* @date 2020/12/21
*/
public class Test {
public static void main(String[] args) {
DynamicProxy dynamicProxy = new DynamicProxy(new HeFei());
BeiJing beiJing = (BeiJing) dynamicProxy.getProxyInstace();
beiJing.sale("华硕");
}
}
四、Cglib代理
Cglib代理,只能代理普通类,代理过程中相当于为被代理类创建了一个子类。代理类 需要实现 MethodInterceptor
接口
案例:用户添加 并进行权限校验
被代理类:
/**
* @author Object(object_hui@sina.com)
* @description 用户服务
* @date 2020/12/21
*/
public class UserService {
public void add(){
System.out.println("添加用户");
}
}
Cglib代理类:
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @author Object(object_hui@sina.com)
* @description Cglib代理类
* @date 2020/12/21
*/
public class CglibProxy implements MethodInterceptor {
private Object target;
public CglibProxy() {
}
public CglibProxy(Object target) {
this.target = target;
}
public Object getCglibProxyInstance(){
//创建代理对象
Enhancer enhancer = new Enhancer();
//设置代理对象父类的信息
enhancer.setSuperclass(target.getClass());
//回调当前对象
enhancer.setCallback(this);
//返回创建的对象
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//权限校验
Security.security();
//执行调用方法
return methodProxy.invokeSuper(o,objects);
}
}