面试总结:AOP

AOP(面向切面编程)是OOP的延申。
在处理业务的过程中,通过调用对象的方法可以完成对业务的处理;但是如果在业务处理之前要进行一些非核心的处理,如输出日志或做空值判断,这些非核心代码并不重要,并且是可以重用的,我们不想把它加入到核心代码中,但是在执行核心代码之前又必须要进行非核心的处理,这个时候我们就要用到AOP,其核心思想就是代理。
AOP用到的设计模式就是代理模式,即在不影响原功能的前提下,拓展新的功能。
代理分静态代理动态代理

静态代理
public interface IUserDao {
	public void add();
}

@Component  //相当于生成了userDao的bean
public class UserDaoImpl implements IUserDao {
	@Override
	public void add() {
		System.out.println("userDao add...");	
	}
}

public class Proxy implements IUserService{
	private IUserService userService;
	
	public Proxy(IUserService userService) {
		this.userService = userService;
	}
	
	@Override
	public void add() {
		before();
		userService.add();
		after();
	}
	void before(){
		//do sth
	}
	void after(){
		//dosth
	}
}

这就是静态代理,很简单,只需要创建一个代理类也去继承相同的接口,重写对应的方法,并在构造函数里面初始化被代理类的对象,在调用核心代码之前,就可以执行其他的非核心代码,并且不影响原功能。
静态代理的缺点:需要再创建一个类去继承接口,增强代码在编译期就会被织入,并且接口变动或实现类变动时,代码变动较大。

动态代理

JDK动态代理

public class MyMainApp {
    public static void main(String[] args) {
        //静态代理
       // MyProxy myProxy = new MyProxy();
        //myProxy.add();

        //动态代理
        IUserDao userA = new UserA();
        IUserDao proxyInstance = (IUserDao) Proxy.newProxyInstance(UserA.class.getClassLoader(), UserA.class.getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                if (method.getName().equals("add")){
                    System.out.println("before...");
                    method.invoke(userA, args);
                }
                return null;
            }
        });
        proxyInstance.add();
    }
}

这里用到了java.lang.reflect包里的Proxy类,可以看到JDK动态代理要获取到代理对象需要传入3个参数:
1.被代理类的类加载器
2.被代理类的接口
3.InvocationHandler的实现类
所以,如果被代理类没有接口,那么就不能用JDK动态代理,需要用CGLib动态代理。
CGLib动态代理

class MyCGLibProxy implements MethodInterceptor{

    private IUserDao userDao;

    public MyCGLibProxy(IUserDao userDao) {
        this.userDao = userDao;
    }

    public IUserDao getProxy(){
        //CGLib动态代理
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(IUserDao.class);
        enhancer.setCallback(this);
        return  (IUserDao) enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("before...");
        method.invoke(userDao, args);
        return null;
    }
}

CGLib需要使用Enhancer类来创建代理对象,创建代理时需要传入被代理对象的父类(所有类都有一个公共的父类Object)。
AOP同时采用JDK和CGLib两种代理方式,默认JDK动态代理方式。

@Component
@Aspect  //切面类
public class MyAspect {
	//设置前置增强 * 包名+类名+方法名+(..)
	@Before("execution(* com.zq.service.impl.*.*(..))")
	public void before(){
		System.out.println("before....");
	}
	
	//设置后置增强
	@After("execution(* com.zq.service.impl.*.*(..))")
	public void after(){
		System.out.println("after....");
	}
}

SpringAOP使用场景:如计算程序执行时间,输出日志等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值