您的位置:首页 > 运维架构

AOP解密-----AOP之动态代理实现

2016-11-16 20:55 169 查看

1、前提:最初要实现的功能(打招呼)

                      



代码:

接口:

public interface Greeting {
void sayHello(String name);
}
实现:

public class GreetingImpl implements Greeting {
@Override
public void sayHello(String name) {
System.out.println("Hello! " + name);
}


2、要增加一个功能,在打招呼前加入打印“befor”,在打招呼后打印“after”
                  


修改后实现:

public class GreetingImpl implements Greeting {
@Override
public void sayHello(String name) {
before();
System.out.println("Hello! " + name);
after();
}
private void before() {
System.out.println("Before");
}
private void after() {
System.out.println("After");
}
}


       
如果有一天,上图 中的Before和After方法的代码段需要修改,那是不是要打开代码进行修改?如果 100 个地方,甚至是 1000 个地方包含这段代码段,那会是什么后果?

3、静态代理的实现

      使用静态代理的方法,解决是提出上面的问题。

                 


代理的实现:

public class GreetingProxy implements Greeting {
private Greeting greeting;
public GreetingProxy(GreetingImpl greetingImpl) {
this.greeting = greetingImpl;
}
@Override
public void sayHello(String name) {
before();
greeting.sayHello(name);
after();
}
private void before() {
System.out.println("Before");
}

private void after() {
System.out.println("After");
}
}
注意:这时候,GreetingImpl里没有befor和after方法。具体的逻辑实现,是在代理类GreetingProxy里面实现的。

4、JDK动态代理的实现

       因为软件系统需求变更是很频繁的事情,系统前期设计方法 1、方法 2、方法 3 时只实现了核心业务功能,过了一段时间,我们需要为方法 1、方法 2、方法 3 都增加事务控制;又过了一段时间,客户提出方法 1、方法 2、方法 3 需要进行用户合法性验证,只有合法的用户才能执行这些方法;又过了一段时间,客户又提出方法 1、方法 2、方法 3 应该增加日志记录;又过了一段时间,客户又提出……面对这样的情况,我们怎么办?

        3.1 类设计

              


        3.2 代码实现

public class JDKDynamicProxy implements InvocationHandler {
private Object target;
public JDKDynamicProxy(Object target) {
this.target = target;
}
@SuppressWarnings("unchecked")
public <T> T getProxy() {
return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
before();
Object result = method.invoke(target, args);
after();
return result;
}
private void before() {
System.out.println("Before");
}
private void after() {
System.out.println("After");
}
}


        3.3 测试代码

public class Client2 {
public static void main(String[] args) {
Greeting greeting2 = new JDKDynamicProxy(new GreetingImpl()).getProxy();
greeting2.sayHello("Jack");
}
}


        3.4 运行的对象的关系

              


4、CGLIB动态代理的实现
      使用JDk动态代理实现的缺点:必须要实现接口。

      改进:使用CGLIB的动态代理

       4.1 类设计

             


       4.2 代码实现

public class CGLibDynamicProxy implements MethodInterceptor {
private static CGLibDynamicProxy instance = new CGLibDynamicProxy();
private CGLibDynamicProxy() {
}
public static CGLibDynamicProxy getInstance() {
return instance;
}
@SuppressWarnings("unchecked")
public <T> T getProxy(Class<T> cls) {
return (T) Enhancer.create(cls, this);
}
private void before() {
System.out.println("Before");
}
private void after() {
System.out.println("After");
}
@Override
public Object intercept(Object target, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
before();
Object result = proxy.invokeSuper(target, args);
after();
return result;
}
}


       4.3 测试代码

public class Client2 {
public static void main(String[] args) {
GreetingImpl greeting = CGLibDynamicProxy.getInstance().getProxy(
GreetingImpl.class);
greeting.sayHello("Jack");
}
}


       4.4 运行时对象的关系

           

 

5、参考博客

http://blog.csdn.net/xvshu/article/details/46288131


6、源码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息