11-25 程宗武

11-25 Spring03

1.AOP

AOP: 面向切面编程。把重复的代码抽取,在需要使用的地方,使用动态代理的技术,对原有的方法进行增强

1.1 动态代理

字节码随用随创建,随用随加载。

1.1.1基于接口的动态代理

JDK的Proxy类 ,要求被代理类最少实现一个接口

public class Actor implements IActor {
    public void basicAct(float money) {
        System.out.println("成龙基本演出收入:" + money);
    }

    public void dangerAct(float money) {
        System.out.println("成龙危险演出收入:" + money);
    }

    public static void main(String[] args) {
        final Actor actor = new Actor();
        //这里因为传入的是被代理的是接口类型,所以也要用接口类型的来接收 但实际执行的是实现类中的方法
        IActor proxyInstance = (IActor)  Proxy.newProxyInstance(actor.getClass().getClassLoader(), actor.getClass().getInterfaces(), new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                String name = method.getName();
                Float money = (Float) args[0];
                Object returnValue = null;
                if ("basicAct".equalsIgnoreCase(name)) {
                    if (money >= 5000) {
                        returnValue = method.invoke(actor, money / 2);
                    }
                }
                if ("dangerAct".equalsIgnoreCase(name)) {
                    if (money >= 10000) {
                        returnValue = method.invoke(actor, money / 2);
                    }
                }
                return null;
            }
        });
        proxyInstance.basicAct(5000);
        proxyInstance.basicAct(10000);
    }
}

1.1.2基于子类的动态代理

第三方的 CGLib,要求被代理类不能用 final 修饰的类(最终类)。

maven的坐标

<dependencies>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.1_3</version>
        </dependency>
</dependencies>
public class Actor2 {
    public void basicAct(float money) {
        System.out.println("李连杰基本演出收入:" + money);
    }

    public void dangerAct(float money) {
        System.out.println("李连杰危险演出收入:" + money);
    }

    public static void main(String[] args) {
        final Actor2 actor2 = new Actor2();
        //这里直接用本类类型来接收
        Actor2 proxyActor = (Actor2) Enhancer.create(actor2.getClass(), new MethodInterceptor() {
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                String name = method.getName();
                Float money = (Float) args[0];
                Object returnValue = null;
                if ("basicAct".equalsIgnoreCase(name)) {
                    if (money >= 5000) {
                        returnValue = method.invoke(actor2, money / 2);
                    }
                }
                if ("dangerAct".equalsIgnoreCase(name)) {
                    if (money >= 10000) {
                        returnValue = method.invoke(actor2, money / 2);
                    }
                }
                return returnValue;
            }
        });
        proxyActor.basicAct(5000);
        proxyActor.dangerAct(10000);
    }
}

注: 在执行被代理类中的任何方法时,都会经过这个动态代理处理过后的方法 例: public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 相当于一个拦截器。然后对被代理类中相应的方法进行处理过后,再执行。

标签

评论

© 2021 成都云创动力科技有限公司 蜀ICP备20006351号-1