spring基础(AOP)
2019-08-13 本文已影响0人
鸡龙
什么是AOP(面向切面)
AOP可以说是OOP(面向对象)的补充和完善,OOP中有封装、继承、多态来建立一种对象层次结构,OOP允许你定义从上到下的关系,但却不适合定义从左到右的关系。例如日志功能。输出日志的代码往往水平地散步在所有对象层次中,但他却和核心功能毫不相关,这种散布到各处的代码被称为横切代码。
而AOP却可以通过横切技术,将那些与业务无关,却为业务模块所共同调用的逻辑进行封装起来降低模块间的耦合度。
AOP原理(代理)
AOP实际上就是由目标类的代理类实现的。就像夹汉堡一样。目标类就是其中的一块肉。其他无关操作就是面包,代理类在特定切入点添加了增强处理是面包,并回调方法是肉。
由于是代理实现AOP,而代理又分静态代理和动态代理。
下面代码,如我们需要在调用service方法前后增加try catch,有两种方法,一种是直接在代码中添加try catch,一种是使用代理。由于一个方法可能会被调用多次,却每处都要进行修改,所以我们使用代理模式进行增加功能。
public interface IService {
public void service(String name )throws Exception;
}
public class ServiceImplA implements IService {
@Override
public void service(String name) throws Exception {
System.out.println("ServiceImplA name" + name);
}
}
1、静态代理
静态代理实现很简单,就跟上面所说的,创建一个代理类,类中面包夹肉。但是这样使得每一个接口都需要写一个代理类,所以有了动态代理。
public class ProxyServiceA implements IService {
public IService service;
public ProxyServiceA(IService service){
super();
this.service = service;
}
@Override
public void service(String name) throws Exception {
System.out.println("log start");
try{
service.service(name);
}catch (Exception e){
throw e;
}
System.out.println("log end");
}
public static void main(String []args) throws Exception {
IService service = new ServiceImplA();
service = new ProxyServiceA(service);
service.service("zhjl");
}
}
动态代理
在java中的动态代理机制中,使用了Proxy类和实现了InvocationHandler接口。实现了invoke方法来实现动态代理。
动态代理涉及到了之前反射中的描述方法,通过Proxy.newProxyInstance()生成的动态代理对象都会与实现InvocationHandler接口的对象关联。代理对象调用目标对象的方法时都会变成调用B中的invoke方法。
public class DynaProxyServiceA implements InvocationHandler {
private Object object;
/**
* 将目标对象关联到InvocationHandler接口,返回代理对象obj
* 调用代理对象的方法时,都会自动调用invoke方法
*/
public Object bind(Object object){
this.object = object;
Object obj = Proxy.newProxyInstance(
this.object.getClass().getClassLoader(),
this.object.getClass().getInterfaces(),
this);
return obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result;
System.out.println("log start");
try{
result = method.invoke(this.object,args);
}catch (Exception e){
throw e;
}
System.out.println("log end");
return result;
}
public static void main(String [] args) throws Exception {
IService service = (IService)new DynaProxyServiceA()
.bind(new ServiceImplA());
service.service("zhjl");
}
}
与静态代理不同,动态代理不用再为每个接口手动创建代理类,只要该对象,获取到该对象的class实例,在增强处理中来通过class中的invoke来执行方法。