zoukankan      html  css  js  c++  java
  • 动态代理

    //定义接口
    public interface Foo
    {
    void doAction();
    }
    //实现一
    public class FooImpl implements Foo
    {
    public FooImpl()
    {
    }

    public void doAction()
    {
    System.out.println("in FooImp1.doAction()");
    }
    }
    //实现二
    public class FooImpl2 implements Foo
    {
    public FooImpl2()
    {
    }
    public void doAction()
    {
    System.out.println("in FooImp2.doAction()");
    }

    }
    //代理类
    public class DynamicSubject implements InvocationHandler
    {
    private Object sub;

    public DynamicSubject()
    {
    }

    public DynamicSubject(Object obj)
    {
    sub = obj;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
    System.out.println("before calling " + method);

    method.invoke(sub, args);

    System.out.println("after calling " + method);

    return null;
    }

    }
    //测试
    public class Demo
    {
    public static void main(String[] args)
    {

    // 1.通用的动态代理实现

    CommonInvocationHandler handler = new CommonInvocationHandler();

    Foo f;

    // 2.接口实现1

    handler.setTarget(new FooImpl());

    f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),

    new Class[] { Foo.class },

    handler);

    f.doAction();

    // 3.接口实现2

    handler.setTarget(new FooImpl2());

    f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),

    new Class[] { Foo.class },

    handler);

    f.doAction();
    }
    }
    ----------->>也就是面向接口编程,完全可以写一个工厂类实现的,为什么要采用这个方式,如:

    class Factory{
    Foo fo ;
    public Factory(Foo fo){
    this.fo = fo;
    }
    public Foo getInstence(){
    return fo;
    }
    }
    然后创建Factory对象
    =============》》 有什么差别么??

    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;

    public class AopTest {

    public static void main(String[] args) {

    Before before = new Before() {
    public void before() {
    System.out.println("...before...");
    }
    };

    After after = new After() {
    public void after() {
    System.out.println("...after...");
    }
    };

    Hello hello = null;

    // 普通方法执行
    System.out.println("-------------普通执行-------------");
    hello = new HelloEnglish();
    hello.sayHello("bao110908");
    hello.sayHi("bao110908");
    System.out.println();

    // 切入方法执行前(前置增强)
    System.out.println("-------------前置增强-------------");
    hello = HelloAopManager.getHelloProxy(new HelloEnglish(), before);
    hello.sayHello("bao110908");
    hello.sayHi("bao110908"); // sayHi 方法没有标注 @Enhancement 所以不会进行代码切入
    System.out.println();

    // 切入方法执行后(后置增强)
    System.out.println("-------------后置增强-------------");
    hello = HelloAopManager.getHelloProxy(new HelloEnglish(), after);
    hello.sayHello("bao110908");
    hello.sayHi("bao110908");
    System.out.println();

    // 切入方法执行前和执行后(环绕增强)
    System.out.println("-------------环绕增强-------------");
    hello = HelloAopManager.getHelloProxy(new HelloEnglish(), before, after);
    hello.sayHello("bao110908");
    hello.sayHi("bao110908");
    System.out.println();
    }
    }



    @Retention(RetentionPolicy.RUNTIME)
    @interface Enhancement {
    }

    interface Hello {
    @Enhancement
    public void sayHello(String name);
    public void sayHi(String name);
    }

    class HelloChinese implements Hello {
    public void sayHello(String name) {
    System.out.println(name + ",您好");
    }
    public void sayHi(String name) {
    System.out.println("哈啰," + name);
    }
    }

    class HelloEnglish implements Hello {
    public void sayHello(String name) {
    System.out.println("Hello, " + name);
    }
    public void sayHi(String name) {
    System.out.println("hi, " + name);
    }
    }

    class HelloAopManager {
    private HelloAopManager(){
    }

    public static Hello getHelloProxy(Hello hello, Before before) {
    return getHelloProxy(hello, before, null);
    }

    public static Hello getHelloProxy(Hello hello, After after) {
    return getHelloProxy(hello, null, after);
    }

    public static Hello getHelloProxy(Hello hello, Before before, After after) {
    HelloHandler handler = new HelloHandler();
    if(before != null) {
    handler.setBefore(before);
    }
    if(after != null) {
    handler.setAfter(after);
    }
    return handler.bind(hello);
    }
    }

    /**
    * 前置增强接口
    */
    interface Before {
    public void before();
    }

    /**
    * 后置增强接口
    */
    interface After {
    public void after();
    }

    class HelloHandler implements InvocationHandler {

    /**
    * 需要进行代理的实例
    */
    private Hello hello = null;

    /**
    * 前置增强
    */
    private Before before = null;

    /**
    * 后置增强
    */
    private After after = null;

    /**
    * InvocationHandler 接口的实现方法,进行动态代理
    */
    public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable {
    // 看看接口中方法是否标注了需要 Enhancement
    boolean b = method.isAnnotationPresent(Enhancement.class);
    if(!b){
    // 没有标注的话,按原方法执行
    return method.invoke(hello, args);
    }
    // 有标注的话,进行方法的前置和后置增强
    if(before != null) {
    before.before();
    }
    Object obj = method.invoke(hello, args);
    if(after != null) {
    after.after();
    }
    return obj;
    }

    /**
    * 将传入的 Hello 与 InvocationHandler 进行绑定,以获得代理类的实例
    * @param hello
    * @return
    */
    public Hello bind(Hello hello) {
    this.hello = hello;
    Hello helloProxy = (Hello)Proxy.newProxyInstance(
    hello.getClass().getClassLoader(),
    hello.getClass().getInterfaces(),
    this
    );
    return helloProxy;
    }

    public void setAfter(After after) {
    this.after = after;
    }

    public void setBefore(Before before) {
    this.before = before;
    }
    }

  • 相关阅读:
    如何把.cs文件编译成DLL文件
    单元测试的性能测试库
    MVC5在Mono上的各种坑
    基于Selenium的自动化测试 C#版(1)
    关于最近的CSRF攻击
    ILspy反编译工具
    关于公司内部的Nuget服务
    log4net入门
    java 多线程以及线程池
    Arraylist 和 linkedlist || hashset 和treeset. || hashMap 和 TreeMap
  • 原文地址:https://www.cnblogs.com/peijie-tech/p/3409111.html
Copyright © 2011-2022 走看看