Spring

93 阅读2分钟

特点:

  • 1.IOC 控制反转
  • 2.AOP 面向切面编程
  • 3.容器
  • 4.组件化
  • 5.一站式
  • 6.非侵入式

IOC 注入 分set 注入和构造器注入 工厂模式+反射(反射如何实现看基础)

AOP 代理模式 (静态代理和动态代理) -- 解耦

静态代理

public class CalculatorStaticProxy implements Calculator {



    //被代理目标对象传过来
    private  Calculator calculator;

    public CalculatorStaticProxy(Calculator calculator) {
        this.calculator = calculator;
    }
    @Override
    public int add(int a, int b) {
        System.out.println("日志开始");
       //调用目标对象的方法实现核心业务
        int result = calculator.add(a, b);
        System.out.println(result);
        System.out.println("日志结束");
        return result;
    }
 }   

动态代理 jdk代理(有接口,生成接口实现类) cglib代理(没有接口,生成子类代理对象)

package com.spring;

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

public class ProxyFactory {


    //目标对象
    private Object object;


    public ProxyFactory(Object object) {
        this.object = object;
    }

    //创建方法返回代理对象
    public Object getProxy() {
        /**
         * 有三个参数
         *
         *1.ClassLoader: 类加载器
         * 2.Class[] interfaces: 目标对象实现的所有接口的class的数组
         * 3.InvocationHandler: 设置代理对象实现目标对象方法的过程
         *
         */
        ClassLoader classLoader = object.getClass().getClassLoader();
        Class<?>[] interfaces = object.getClass().getInterfaces();
        InvocationHandler invocationHandler = new InvocationHandler() {


            /**
             *
             * @param proxy 代理对象
             * @param method 需要重写目标对象
             * @param args 对应方法参数
             * @return
             * @throws Throwable
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //调用之前输出
                System.out.println("动态代理" + method.getName());
                //调用目标方法
                Object invoke = method.invoke(object, args);
                //调用之后输出
                System.out.println("动态代理" + method.getName());
                return invoke;
            }
        };
        return Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
    }
}

1.横切关注点 2.通知(增强) 3.切面 4.目标 5.代理 6.连接点 7.切入点

package com.spring.anoaop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.junit.jupiter.api.Test;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Aspect
@Component
public class LogAspect {
    //设置切入点和通知类型
    //切入点表达式 execution (public int 全类名 方法名 (参数))
    //通知类型:
    // 前置 @Before() (value = "切入点表达式")
    @Before(value = "execution(public int com.spring.anoaop.CalculatorImpl.*(..))")
    public  void  beforeMethod(){
        System.out.println("输出前置通知");
    }
    // 返回  @AfterReturning
    @AfterReturning(value = "execution(* com.spring.anoaop.CalculatorImpl.*(..))",returning = "result")
    public void afterReturningMethod(JoinPoint joinPoint,Object result){
        String name = joinPoint.getSignature().getName();
        System.out.println("输出返回通知 方法名称"+name+"结果"+ result);
    }
    // 异常   @AfterThrowing
    @AfterThrowing(value = "execution(* com.spring.anoaop.CalculatorImpl.*(..))",throwing = "ex")
    public void afterThrowingMethod(JoinPoint joinPoint,Throwable ex){
        String name = joinPoint.getSignature().getName();
        System.out.println("输出异常通知 方法名称"+name+"异常"+ex);
    }
    // 后置 @After()
    @After(value = "execution(* com.spring.anoaop.CalculatorImpl.*(..))")
    public void afterMethod(JoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        System.out.println("输出后置通知 方法名称"+name);
    }
    // 环绕 @Around()
    @Around(value = "pointCut()")
    public Object aroundMethod(ProceedingJoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        String s = Arrays.toString(args);
        Object result =null;
        try {
            result= joinPoint.proceed();

            System.out.println("环绕通知 执行方法返回通知");

        }catch (Throwable throwable){
            throwable.printStackTrace();
            System.out.println("环绕通知 异常执行");
        }finally {
            System.out.println("输出环绕通知 最终通知");
        }
        return result;
    }

    //重用切入点表达式
    @Pointcut(value = "execution(* com.spring.anoaop.CalculatorImpl.*(..))")
    public void pointCut(){

    }
}