AOP简述

AOP

含义

面向切面编程:

  • 抽取公共逻辑;利用动态代理方式。在目标方法执行前后动态插入指定逻辑
  • jdk提供动态代理:必须有接口
  • cglib提供动态代理:任意类;

面向对象编程:

面向过程编程:
纵向关系 OOP,横向角度 AOP

AOP的目标是把这些功能集中起来,放到一个统一的地方来控制和管理。利用 AOP 思想,这样对业务逻辑的各个部分进行了隔离,从而降低业务逻辑各部分之间的耦合,提高程序的可重用性,提高开发效率。



 <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-aopartifactId>
 dependency>
public class SampleClass {
    public void test(){
        System.out.println("hello world");
    }

    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(SampleClass.class);
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                System.out.println("before method run...");
                Object result = proxy.invokeSuper(obj, args);
                System.out.println("after method run...");
                return result;
            }
        });
        SampleClass sample = (SampleClass) enhancer.create();
        sample.test();
    }
}

创建代理的各种方式

public class DynamicProxy {

    /**
     * 测试cglib
     * @param args
     */
    public static void main(String[] args) {
        BMW bmw = new BMW();
        bmw.gogo();

        //1、创建增强器
        Enhancer enhancer = new Enhancer();
        //2、指定父类
        enhancer.setSuperclass(BMW.class);
        //3、设置回调
        enhancer.setCallback(new MethodInterceptor() {
            /**
             * 调用每个方法都会进入拦截器;
             * @param o:  当前创建好的代理对象
             * @param method:  方法
             * @param args: 参数
             * @param methodProxy: 代理方法
             * @return
             * @throws Throwable
             */
            @Override
            public Object intercept(Object o,
                                    Method method,
                                    Object[] args,
                                    MethodProxy methodProxy) throws Throwable {
//                System.out.println(method);
//                method.invoke(bmw,args); //真正执行目标方法
//                System.out.println(args);
//                System.out.println(methodProxy);

                //执行父类方法才行
                System.out.println("加油");
                System.out.println("启动");
                Object invokeSuper = methodProxy.invokeSuper(o, args);
                System.out.println("停车");
                return invokeSuper;
            }
        });

        System.out.println("======");

        //4、创建代理对象
        BMW m = (BMW) enhancer.create();
        m.gogo();

    }


    /**
     * 测试动态代理
     * @param args
     */
    public static void aaa(String[] args) {
        //1、创建普通对象
        Wuling wuling1 = new Wuling();
        wuling1.setName("Mini EV1");

        Wuling wuling2 = new Wuling();
        wuling2.setName("Mini EV2");
//
//        Wuling wuling3 = new Wuling();
//        wuling3.setName("Mini EV3");

        wuling1.gogo();

//        wuling3.gogo();


        //代理对象
        Car proxy = (Car) Proxy.newProxyInstance(
                wuling1.getClass().getClassLoader(),
                wuling1.getClass().getInterfaces(),
                new InvocationHandler() {
                    /**
                     *
                     * 明星、经纪人
                     *
                     * @param proxy   代理对象:经纪人
                     * @param method  当前方法:
                     * @param args    参数
                     * @return
                     * @throws Throwable
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //1、利用反射执行方法
                        System.out.println("代理正在执行..."+this);

                        //执行真正的目标方法
                        //1、方法执行之前: 前置通知
                        Object invoke = null;
                        try {
                            invoke = method.invoke(wuling2, args);
                            //2、目标方法正常执行完成: 返回通知
                        }catch (Exception e){
                            //3、异常完成: 异常通知

                        }finally {
                            //4、最终都要做的事情:后置通知
                        }

                        return invoke;
                    }
                }
        );

        System.out.println("=============");
        proxy.gogo();
        System.out.println("=============");

        wuling2.gogo();
    }

}
interface Car {
    void gogo();
}

class BMW {
    public void gogo(){
        System.out.println( "BMW == 汽车行驶中....");
    }
}

@Data
class Wuling implements Car {

    private String name;



//    @Override
    public void gogo(){
        //jiayou()
        //startengine()
        System.out.println(name + " == 汽车行驶中....");
        //park();
    }
}

切面:实现缓存逻辑抽取

1、引入starter

 <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-aopartifactId>
        dependency>

2、开启基于注解的AOP功能

@EnableAspectJAutoProxy

3、编写一个切面

利用环绕通知才能拦截目标方法的执行

@Component //加入容器中才能生效
@Aspect //声明这是一个切面
public class CacheAspect {

    @Pointcut("execution(public * com.example.item.service.SkuDetailService.getSkuDetailData(..))")
    public void pc(){};


    //拦截目标方法的执行:
    //连接点:封装了目标方法与当前切面信息;
    //环绕通知:
    @Around(value = "pc()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        Object retVal = null;
        try {

            // 执行目标方法
            retVal = pjp.proceed();
        }finally {

        }
        return retVal;
    }
}

SpEL

参考文档:Core Technologies (spring.io)

public class ExpressionTest {


    @Test
    void test02(){
        //1、创建一个表达式解析器
        ExpressionParser parser = new SpelExpressionParser();
        //2、解析一个表达式;定界符  //sku:info:#{#args[1]}
        Expression expression = parser.parseExpression("#{1+1}",
                ParserContext.TEMPLATE_EXPRESSION);

        //3、得到值
        EvaluationContext ec = new StandardEvaluationContext();
        ec.setVariable("args",new Long[]{88L,77L,45L});
//        ec.setVariable("sms",new SmsService());
        String value = expression.getValue(ec, String.class);
        System.out.println(value);
    }

    @Test
    void test01(){
        //1、创建一个表达式解析器
        ExpressionParser parser = new SpelExpressionParser();
        //2、解析一个表达式
        String s = UUID.randomUUID().toString();
        Expression expression = parser.parseExpression("T(java.util.UUID).randomUUID().toString()");
        //3、得到表达式计算出来的值
        Object value = expression.getValue();
        System.out.println("最终的值:"+value);
    }

    public static class Person {
        public String haha(){
            System.out.println("hahaha....");
            return "666";
        }
    }
}

你可能感兴趣的:(java,开发语言)