运用代理实现AOP编程
运用AOP思想指导,进行打印日志到控制台。实现方式可以选择静态代理和动态代理。
AOP(Aspect Oriented Programming,面向切面编程),运用分层的思想进行开发,已经是相当普遍行为了。而AOP则相当于,在原来的分层基础上,在层与层之间再添加一层,在新添加的一层中加入一些处理(如日志记录,性能统计,安全控制,事务处理,异常处理)。
静态代理,需要为每一个被代理类建立对应的代理类,好处是业务逻辑清晰了(业务处理代码与控制信息相分离),弊端也是明显的,程序变得庞大了。
静态代理的【基本条件】:被代理的类必须实现于接口。代理类也实现该接口。
动态代理,代理类是动态生成的,并且是隐藏于JVM中的,因而,只需写一个动态代理类,就能灵活适用于所有的被代理类。使用时,传入被代理类,代理类读出传递过来的类的信息,对其进行装配和控制。
动态代理的【基本条件】:实现InvocationHandler接口,通过 invoke()方法 进行拦截的。
//************************************************************************************************************************************************
以下2个示例的【前情提要】:
public interface FlowCardManager{……}
public class FlowCardManagerImpl implements FlowCardManager{ ……}
*************************************************************************************************************************************************************************//
静态代理的仅仅是将原来的调用实现类改成调用代理,同时传入实现类,在代理类中调用传入的实现类的方法。相当于方法调用,在方法的前后加入控制信息。示例:
public class FlowCardManagerImplProxy implements FlowCardManager {
private FlowCardManager flowCardManager;
public FlowCardManagerImplProxy(FlowCardManager flowCardManager) {
this.flowCardManager = flowCardManager;
}
@Override
public void addFlowCard(FlowCard flowCard) throws ApplicationException {
try {
System.out.println("执行addFlowCard()前添加的控制信息");
// flowCardManager目标类的实例对象
flowCardManager.addFlowCard(flowCard);
System.out.println("执行addFlowCard()成功!");
} catch (Exception e) {
e.printStackTrace();
System.err.println("执行addFlowCard()失败。");
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
// 原来的调法
// FlowCardManager flowCardManager = new FlowCardManagerImpl();
// 由原来的调用目标类,改成调用代理类,并将目标类实例对象传入代理类中
FlowCardManager flowCardManager = new FlowCardManagerImplProxy(new FlowCardManagerImpl());
flowCardManager.addFlowCard(new FlowCard());
}
}
动态代理的灵活装配给程序带来的便利度更高些。有了传入的目标类,通过getClass().getClassLoader()方法获取目标类的加载器,通过getClass().getInterfaces()取得目标类的接口集合,加上目标类本身。有了这些信息,就可以对目标类进行代理控制了。示例:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.bjpowernode.drp.flowcard.domin.FlowCard;
import com.bjpowernode.drp.flowcard.manager.FlowCardManager;
import com.bjpowernode.drp.flowcard.manager.FlowCardManagerImpl;
public class LogHandler implements InvocationHandler {
private Object targetObject;
public Object newProxyInstance(Object targetObject) {
this.targetObject = targetObject;
/**
* getClassLoader():类加载器
* getInterfaces():接口集
* this:类-自身
*/
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// 执行前打印
System.out.println("star--->>" + method.getName());
String argstring = null;
Object rs = null;
// 读取参数列表
for (int i = 0; i < args.length; i++) {
argstring += args[i].toString();
}
System.out.println("参数列表:"+ argstring);
try {
// 执行目标类方法
rs = method.invoke(targetObject, args);
// 执行成功,打印
System.out.println("seccuss--->>" + method.getName());
} catch (Exception e) {
e.printStackTrace();
// 失败时打印
System.out.println("err--->>" + method.getName());
throw e;
}
return rs;
}
public static void main(String[] args) {
// 日志记录-代理类
LogHandler logHandler = new LogHandler();
// 向代理类传入 目标类对象实例
FlowCardManager flowCardManager = (FlowCardManager)logHandler.newProxyInstance(new FlowCardManagerImpl());
// 调用代理类的方法执行控制
flowCardManager.addFlowCard(new FlowCard());
}
}
动态代理实现AOP思想,跟过滤器的思想有相同之处,都是通过了过滤,使得所有通过该过滤的方法都受到其影响。