动态代理实现AOP
代理
代理顾名思义:代为处理。不是对目标对象的直接操作,而是通过代理对目标对象进行包装,此时可以在目标对象的基础上添加额外的操作以满足业务需求。图示

分类:动态代理、静态代理。
代理三要素:共同接口、真实对象、代理对象

引入代理的原因:
在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用【解耦】。
静态代理
public interface Action {
public void doSomething();
}
public class Proxyc implements Action{
Action realObject;
public Proxyc(Action action) {
realObject = action;
}
@Override
public void doSomething() {
System.out.println("被拦截前...");
realObject.doSomething();
System.out.println("被拦截后...");
}
public static void main(String[] args) {
Proxyc proxy = new Proxyc(new RealObject());
proxy.doSomething();
}
}
优点:扩展原功能,不侵入代码
缺点:假如有10个不同的实际对象,对应10个不同的方法,该如何写呢?
1) 要么创建不同的代理类,代理后这样:
proxy.doSomething()
proxy2.doSomething2()
proxy3.doSomething3()
...
问题:创建多个功能类似的代理类,仅传入的真实对象不同
2) 要么创建一个代理,实现不同的接口:
proxy.doSomething()
proxy.doSomething2()
proxy.doSomething3()
...
问题:代理类不断膨胀
动态代理
代理由静态转为静态源于静态代理引入的额外工作。
动态代理就是我们上面提到的方案一,只不过这些proxy的创建都是自动的并且是在运行期生成的。
很多繁琐的编程可以用动态代理解决
实现方式
- 反射(依赖接口)
- 优点:最小化依赖关系;平滑jdk升级;代码简单
- cglib等(依赖子类)
- 优点:不限制实现接口;只操作关心的类;高性能
反射方式举例
public interface Action {
public void doSomething();
}
public class RealObject implements Action{
@Override
public void doSomething() {
System.out.println("I'm RealObject~");
}
}
public class DynamicProxyHandler implements InvocationHandler {
private Object realObject;
public DynamicProxyHandler(Object realObject) {
this.realObject = realObject;
}
@Override
public Object invoke(Object object, Method method, Object[] args) {
Object result = null;
try {
result = method.invoke(realObject, args);
} catch (InvocationTargetException|IllegalAccessException e) {
e.printStackTrace();
}
return result;
}
public static void main(String[] args) {
RealObject realObject = new RealObject();
Action action = (Action) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Action.class},
new DynamicProxyHandler(realObject));
action.doSomething();
}
}
通过Proxy.newProxyInstance()生成代理对象,需要传入3个参数:classLoader + 代理接口 + InvocationHandler实例,
其中InvocationHandler接口,该接口定义了一个invoke方法,proxy最是最终生成的一个代理实例,一般不会用到,参数method是被代理目标实例的某个具体的方法,通过它可以发起目标实例方法的反射调用;参数args是通过被代理实例某一个方法的入参,在方法反射调用时候使用,通过代理将横切逻辑代码和业务类的代码编织到了一起。
动态代理的应用场景
日志
监控
鉴权
......
AOP
切面编程,是对OOP(面向对象编程)的一种补充,解决OOP其对对于跨越不同类、对象,纠缠逻辑变现的不足
AOP实例1
public interface Waiter {
public void service();
}
public class ManWaiter implements Waiter{
@Override
public void service() {
System.out.println("service...");
}
}
public interface BeforeAdvice {
public void before();
}
public interface AfterAdvice {
public void after();
}
@Getter
@Setter
public class ProxyFactory {
Object target;
BeforeAdvice beforeAdvice;
AfterAdvice afterAdvice; public Object createProxy() {
ClassLoader classLoader = this.getClass().getClassLoader();
Class[] interfaces = target.getClass().getInterfaces();
InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (beforeAdvice != null) {
beforeAdvice.before();
}
Object result = method.invoke(target, args);
afterAdvice.after();
return result;
}
};
Object proxyObject = Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
return proxyObject;
} public static void main(String[] args) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(new ManWaiter());
proxyFactory.setBeforeAdvice(new BeforeAdvice() {
@Override
public void before() {
System.out.println("Before Service.");
}
});
proxyFactory.setAfterAdvice(new AfterAdvice() {
@Override
public void after() {
System.out.println("After Service.........");
}
});
Waiter waiter = (Waiter)proxyFactory.createProxy();
waiter.service();
}
}
AOP实例2
public interface UserService {
public void service();
}
public class UserServiceImpl implements UserService{
@Override
public void service() {
System.out.println("In Service.......");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Service end.");
}
}
public class MethodPerformance {
private long start;
private long end;
String serviceMethod;
public MethodPerformance(String serviceMethod) {
this.serviceMethod = serviceMethod;
start = System.currentTimeMillis();
}
public void printPerformance() {
end = System.currentTimeMillis();
System.out.println(serviceMethod + " cost Time: " + (end - start));
}
}
public class PerformanceMonitor {
public static ThreadLocal<MethodPerformance> performanceThreadLocal = new ThreadLocal<>();
public static void begin(String method) {
System.out.println("Start monitor>>");
MethodPerformance methodPerformance = new MethodPerformance(method);
performanceThreadLocal.set(methodPerformance);
}
public static void end() {
System.out.println("End monitor.");
performanceThreadLocal.get().printPerformance();
}
}
public class PerformanceHandler implements InvocationHandler {
Object target;
public PerformanceHandler(Object object) {
target = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) {
Object result = null;
try {
PerformanceMonitor.begin(target.getClass().getName() + ":" + method.getName());
result = method.invoke(target, args);
PerformanceMonitor.end();
} catch (IllegalAccessException| InvocationTargetException e) {
e.printStackTrace();
}
return result;
}
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
ClassLoader classLoader = userService.getClass().getClassLoader();
Class[] interfaces = userService.getClass().getInterfaces();
InvocationHandler invocationHandler = new PerformanceHandler(userService);
UserService obj = (UserService) Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
obj.service();
}
}
动态代理实现AOP的更多相关文章
- 动态代理到基于动态代理的AOP
动态代理,是java支持的一种程序设计方法. 动态代理实现中有两个重要的接口和类,分别是InvocationHandler(interface),Proxy(class). 要实现动态代理,必须要定义 ...
- 动态代理实现AOP【转】
http://blog.csdn.net/beijiguangyong/article/details/8624016 根据前面介绍的Proxy和InvocationHandler,实在很难看出这种动 ...
- .Net 动态代理,AOP
.Net 动态代理,AOP 直接上代码了. /***************************************** * author:jinshuai * * E-mail:redfox ...
- 动态代理的两种方式,以及区别(静态代理、JDK与CGLIB动态代理、AOP+IoC)
Spring学习总结(二)——静态代理.JDK与CGLIB动态代理.AOP+IoC 目录 一.为什么需要代理模式 二.静态代理 三.动态代理,使用JDK内置的Proxy实现 四.动态代理,使用cg ...
- Java动态代理-->Spring AOP
引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓“登高必自卑,涉远必自迩”.以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系列分别介绍这些Jav ...
- .Net 框架实现AOP(动态代理实现AOP,本文为翻译)
在上一节,我们将静态实现AOP,但是对于一个大型项目,要想为每个类,每个方法都去实现AOP ,进行日志记录和权限验证似乎是不可能的. 即使可能对于成百上千个类维护,也是很难维护.所以今天的主题就是如标 ...
- Java使用动态代理实现AOP
参考资料: http://www.importnew.com/15420.htmlhttp://www.cnblogs.com/techyc/p/3455950.html Spring是借助了动态代理 ...
- DispatchProxy实现动态代理及AOP
DispatchProxy类是DotnetCore下的动态代理的类,源码地址:Github,官方文档:MSDN.主要是Activator以及AssemblyBuilder来实现的(请看源码分析),园子 ...
- Java 动态代理与AOP
动态代理与AOP 代理模式 代理模式给某一个目标对象(target)提供代理对象(proxy),并由代理对象控制对target对象的引用. 模式图: 代理模式中的角色有: 抽象对象角色(Abstrac ...
- Java 动态代理及AOP实现机制
AOP实现机制http://www.iteye.com/topic/1116696 AOP: (Aspect Oriented Programming) 面向切面编程AOP包括切面(aspect).通 ...
随机推荐
- Logback简单使用
1. 添加jar包/maven配置 <dependency> <groupId>ch.qos.logback</groupId> <artifactI ...
- WBS分析
我们的产品是2048是一个基于安卓平台开发的小游戏,WBS如下: 进一步优化版本: 小组最终版本:
- nice coding (与其亡羊补牢,不如未雨绸缪)
一.需求前 架构规范 建模规范 编码规范(流程控制,方法抽取,日志打印等) <Effective Java> <Design Patterns> 二.需求中 1. 明确需求(别 ...
- ES6学习:两个面试题目--关于模板字符串
号称看完就能“让开发飞起来”,不过文中的两个面试题目的知识点并没包括在文中. https://www.jianshu.com/p/287e0bb867ae 文中并没有完整的知识点去完成上面的两道题,这 ...
- Linux-VMware Workstation&CentOS-5.5-i386-bin-DVD安装
[2018年6月24日 22:55:47]VM7+CentOS5.5使用NAT方式连接互联网1.在VMWare的菜单:“VM→Setting...” 2.在VMWare的菜单:“Edit→Virtua ...
- JDBC数据库
JDBC是Java程序连接和存取数据库的应用程序接口(API),包括两个包:java.sql和javax.sql. 用JDBC访问数据库的一般步骤: 1.建立数据源 2.装入JDBC驱动程序:使用Cl ...
- eclispe安装tomcate没有srver解决
eclipse没有server选项解决方法 找到Help->InstallNew Software->"Kepler" repository(http:// ...
- ie页面数据导入共享版
为了解决自动输入号码的正确率,原来的版本一直采用鼠标检测的方法.但是这个方法在其他ie平台的使用不太方便.于是直接检测ie的方法.现在的这个版本完全不需要鼠标的检测.方便而且快速精准可靠. 经过作者的 ...
- Linux安装gcc/g++
直接使用yum安装 yum install gcc yum -y install gcc-c++ 如果为RedHat yum需要注册 可以参考更换yum源 https://www.cnblogs.c ...
- Python之旅Day8 socket网络编程
socket网络编程 Socket是网络编程的一个抽象概念.通常我们用一个Socket表示“打开了一个网络链接”,而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型即可.soc ...