测试老兵 代理模式

CC · 2019年01月05日 · 125 次阅读

AOP 说明

常见叫法,面向切面编程,实际原理就是代理模式,即在调用方法做前置处理或后置处理

代理模式

0x01 静态代理模式

package com.finger.test.temp.aopstudy;

/**
 * @Des:
 * @Auther: 飞狐
 * @Date: 2019/1/5
 */
public interface Star {

    void sing();
}

package com.finger.test.temp.aopstudy;

import org.springframework.stereotype.Component;

/**
 * @Des:
 * @Auther: 飞狐
 * @Date: 2019/1/5
 */
@Component("realStar")
public class RealStar implements Star {

    @Override
    public void sing(){
        System.out.println("I love sing");
    }
}


package com.finger.test.temp.aopstudy;

import org.springframework.stereotype.Component;

/**
 * @Des: 静态代理类
 * @Auther: 飞狐
 * @Date: 2019/1/5
 */
@Component("proxyStar")
public class ProxyStar implements Star {

    private Star star;


    public ProxyStar(){

    }

    public ProxyStar(Star star) {
        this.star = star;
    }

    @Override
    public void sing(){
        System.out.println("我在代理明星");
        this.star.sing();
        System.out.println("代言费用很贵");
    }

}

    /**
     * 静态代理实现
     */
    @Test
    public void test1(){
        Star realStar = new RealStar();

        Star proxyStar = new ProxyStar(realStar);

        proxyStar.sing();
    }

0x02 动态代理--JDK 动态代理

package com.finger.test.temp.aopstudy;


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @Des: JDK动态代理方式
 * @Auther: 飞狐
 * @Date: 2019/1/5
 */
public class JdkDynamicProxyStar implements InvocationHandler {

    private Object realStar;

    public JdkDynamicProxyStar(Star star){
        this.realStar = star;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable{
        System.out.println("Hi");
        Object object= method.invoke(realStar,args);
        System.out.println("end");
        return object;
    }

    public <T> T getInstance(){
        return (T)Proxy.newProxyInstance(this.realStar.getClass().getClassLoader(),this.realStar.getClass().getInterfaces(),this);
    }

}

   /**
     * JDK动态代理
     */
    @Test
    public void test2(){

        Star realStar = new RealStar();
        Star proxyStar = new JdkDynamicProxyStar(realStar).getInstance();
        proxyStar.sing();
    }

相对于静态代理动态代理减少对业务接口的依赖降低了代码耦合度JDK动态代理实质是采用Invoke反射机制生成代理类JDK 实现动态代理需要实现类通过接口定义业务方法

0x03 动态代理-CGLIB 代理

对于没有接口的类则采用CGLIB代理进行实现动态代理CGLIB 采用了非常底层的字节码技术其原理是通过字节码技术为一个类创建子类并在子类中采用方法拦截的技术拦截所有父类方法的调用顺势织入横切逻辑但因为采用的是继承所以不能对final修饰的类进行代理

package com.finger.test.temp.aopstudy;


import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @Des: CGLIB动态代理方式
 * @Auther: 飞狐
 * @Date: 2019/1/5
 */
public class CGLIBDynamicProxyStar implements MethodInterceptor {

    private Object realStar;

    public CGLIBDynamicProxyStar(Star star){
        this.realStar = star;
    }


    @Override
    public Object intercept(Object var1, Method var2, Object[] var3, MethodProxy var4) throws Throwable{
        System.out.println("Hi");
        Object object = var4.invokeSuper(var1,var3);
        System.out.println("end");
        return object;
    }


    public <T> T getInstance(){
        Enhancer enhancer = new Enhancer();

        enhancer.setSuperclass(this.realStar.getClass());

        enhancer.setCallback(this);

        return (T) enhancer.create();
    }

   /**
     * CGLIB动态代理方式
     */
    @Test
    public void test3(){

        Star proxyStar = new CGLIBDynamicProxyStar(new RealStar()).getInstance();

        proxyStar.sing();
    }

}


AOP 切面

package com.finger.test.temp.aopstudy;

/**
 * @Des:
 * @Auther: 飞狐
 * @Date: 2019/1/5
 */
public interface SupperStar {

    void sing();
}

package com.finger.test.temp.aopstudy;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * @Des:
 * @Auther: 飞狐
 * @Date: 2019/1/5
 */
@Aspect
@Component
public class AopStar {

    @Pointcut("execution (* com.finger.test.temp.aopstudy.SupperStar.*(..))")
    public void hinihao(){

    }

    @Around("hinihao()")
    public <T> T around(ProceedingJoinPoint joinPoint) throws Throwable{

        System.out.println(joinPoint.getSignature().getName());
        Object result = joinPoint.proceed();

        System.out.println("哈哈哈哈哈");
        return  (T)result;
    }

}

package com.finger.test.temp.aopstudy;

import com.finger.test.base.BaseSupport;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @Des:
 * @Auther: 飞狐
 * @Date: 2019/1/5
 */
public class AopStarTest extends BaseSupport {

    @Autowired
    private SupperStar jiaStar;

    @Test
    public void test(){

        jiaStar.sing();
    }

}


如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册