【Java进阶-Java动态代理与AOP】01 代理类的作用与原理及AOP概念
认识代理
代理的概念与作用
生活中的代理,代理商。我们可以通过代理商买东西,而不需要去工厂区买需要的商品。程序中的代理
- 要为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能,例如,异常处理、日志、计算方法的运行时间、事务管理等等。
- 编写一个与目标类具有相同接口的代理类,代理类的个每个方法调用目标类的相同方法,并在调用方法时加上系统功能的代码。
静态代理示例
interface StaticProxy{
void method();
}
class Target implements StaticProxy{
@Override
public void method() {
System.out.println("Hello world");
}
}
class AdvancedTarget implements StaticProxy{
StaticProxy target = new Target();
@Override
public void method() {
System.out.println("before....");
target.method(); // 调用Target类中的method方法
System.out.println("after....");
}
}
编写一个与目标类具有相同接口的代理类,代理类的每个方法调用目标类的相同方法,并在调用方法时加上系统功能的代码。
Target/AdvancedTarget (目标类和代理类) —-> Interface(目标类和代理类实现相同的接口)
用户类不再直接调用 Target目标类,而是调用 AdvancedTarget 代理类。
如果采用工厂模式和配置文件的方式进行管理,则不需要修改客户端程序,在配置文件中配置是使用目标类还是代理类,这样以后很容易切换,
譬如,想要日志功能时就配置代理类,否则配置目标类,这样增加系统功能很容易,以后运行一段时间后,又想去掉系统功能也很容易。
AOP
AOP――Aspect oriented program,面向方面的编程(面相切片编程)
系统中存在交叉业务,一个交叉业务就是要切入到系统中的一个方面。
安全,事务,日志等功能要贯穿到好多个模块中,所以它们就是交叉业务。
用具体的程序描述交叉业务
method1 method2 method3
{ { {
-----------------------------------------------切面1(安全检查,日志记录)
... ... ...
-----------------------------------------------切面2(安全检查,日志记录)
} } }
交叉业务的编程问题即为面向方面的编程AOP,AOP的目标就是要使交叉业务模块化。
可以采用将切面代码移动到原始方法的周围,这与直接在方法中编写切面代码的运行效果是一样的。如下所示
-----------------------------------------------切面1
func1 func2 func3
{ { {
... ... ...
} } }
-----------------------------------------------切面2
使用代理技术正好可以解决这种问题,代理是实现AOP功能的核心和关键技术。
只要涉及到AOP,就会有代理。
安全、事务、日志等功能要贯穿到好多个模块中,所以他们就是交叉业务。它们并不是对象。
重要原则:不要把供货商暴露给你的客户。
动态代理技术
要为系统中的各种借口的类增加代理功能,那将需要太多的代理类,全部采用静态代理方方式,将是一件复杂的事情!
JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类。
JVM生成的动态类必须实现一个或多个接口,所以,JVM生成的动态类只能用作具有相同接口的目标类的代理。
如果目标类没有实现接口,则需要用CGLIB。CGLIB库(开源工具库,不是JVM的标准)可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB库。
代理类的各个方法中通常除了要调用目标的相应方法和对外返回目标返回的结果外,还可以在代理方法中的如下四个位置加上系统功能代码:
1.在调用目标方法之前
2.在调用目标方法之后
3.在调用目标方法前后
4.在处理目标方法异常的catch块中
参考:
《Java基础强化教程》