2022-9-21 Spring学习笔记

1.Spring

1.1 bean的生命周期

  • 构造器
  • 属性注入
  • 初始化方法
  • 目标方法
  • 销毁方法

延迟初始化(懒初始化)

  • servlet的初始化。默认是延迟初始化。只要不启动,就不会初始化。
  • spring的IOC容器默认就是非延迟初始化。只要spring的容器启动,所有的bean都会加载,都会初始化。

1.2 AOP

面向切面编程,主要用来解决系统层面上的问题,例如:日志,事务,权限

  • 在不改变原有的逻辑的基础上,增加一些儿额外的功能
  • AOP是OOP(面向对象)的补充和完善
  • AOP横切技术,剖解开对象的内部,把一些和业务无关的,却可以为业务共同的调用的逻辑封装起来,减少重复代码的使用。

通知

增强处理(Advice)

  • 先定义好日志,事务或权限,然后再想用的地方,Advice配合Aspect的一段处理代码。

连接点

JoinPoint

就是Spring允许你通知的地方。

  • 例如:一个service层的方法需要配置通知,获取这个方法的参数,方法名,返回值...

切入点

PointCut

一个类中有多个方法,让这些方法中的某几个方法再执行之前,执行之后或抛出异常时做些什么,使用切入点表达式来筛选连接点。

切面

通知和切入点的结合,在什么点上去干什么事

织入

被通知的对象,真正的业务逻辑,可以毫不知情。两者或许之间可能并不知情,专注于自己该做的事。

1.3 配置AOP

使用xml文件配置

<!-- AOP-->
<aop:config>
    <!--        面向切面-->
    <aop:aspect ref="myAop">
        <!--            切点表达式-->
        <aop:pointcut id="logAspectPointCut" expression="execution(* com.jsoft.service.impl.*.*(..))"/>
        <!--           在expression表达式指定的方法执行之前去执行myAop里的before方法
                        pointcut-ref:在什么切点之前-->
        <aop:before method="before" pointcut-ref="logAspectPointCut"></aop:before>
        <!--           在expression表达式指定的方法执行之后去执行myAop里的after方法
            pointcut-ref:在什么切点之后-->
        <aop:after method="after" pointcut-ref="logAspectPointCut"></aop:after>
                    <!--            出现异常执行-->
            <aop:after-throwing method="throwing" pointcut-ref="logAspectPointCut"></aop:after-throwing>
            <!--            成功返回执行-->
            <aop:after-returning method="returning" pointcut-ref="logAspectPointCut"></aop:after-returning>
    </aop:aspect>
</aop:config>

使用注解配置

开启自动扫描

<!-- 开启aop的注解扫描-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

自定义注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyLog {
}

// 带Mylog注解才会执行对应的方法
    @MyLog
    public Account findAccountById(Integer id) {
        System.out.println("findAccountById方法执行中...");
//        int i = 10 / 0;
        return accountDao.findAccountById(id);
    }

注解

@Before("execution(* com.jsoft.service.impl..(..))")

  • 根据表达式
  • 只有满足表达式里的条件的才会执行对应的方法

@Before("@annotation(com.jsoft.annotation.MyLog)")

  • 根据自定义注解
  • 只有在需要用的地方加上自定义的注解,才会执行对应的方法
// 切面注解
@Aspect
public class MyAOP {

//    @Before("execution(* com.jsoft.service.impl.*.*(..))")  表达式
//    @Before("@annotation(com.jsoft.annotation.MyLog)")    根据自定义注释
    public void before(JoinPoint joinPoint) {
        System.out.println("执行方法之前打印一条日志!");
        // 获取目标方法的参数们
        Object[] args = joinPoint.getArgs();
        // 调用目标方法的那个对象
        Object aThis = joinPoint.getThis();
        // 代理对象
        Object target = joinPoint.getTarget();
    }
//    @After("execution(* com.jsoft.service.impl.*.*(..))")
    public void after() {
        System.out.println("执行方法之后打印一条日志!");
    }
//    @AfterThrowing(value = "execution(* com.jsoft.service.impl.*.*(..))",throwing = "e")
    public void throwing(JoinPoint joinPoint,Throwable e) {
        System.out.println("出现了异常...");
        // 获取到异常信息
        System.out.println(e.getMessage());
        // 获取到异常类型
        System.out.println(e.getClass());
    }
//    @AfterReturning(value = "execution(* com.jsoft.service.impl.*.*(..))",returning = "result")
    public void returning(JoinPoint joinPoint,Object result) {
        System.out.println("正常的返回结果...");
        // 方法的返回值
        System.out.println(result);
    }

//    @Around("execution(* com.jsoft.service.impl.*.*(..))")
    public void around(ProceedingJoinPoint joinPoint) {
        System.out.println("before...");
        try {
            // 执行目标方法
            Object o = joinPoint.proceed();
            System.out.println(o);
            System.out.println("returning...");
        }catch (Throwable e){
            System.out.println("throwing...");
        }
        System.out.println("after...");
    }

开启自动扫描后,才能使用注解

1.4 切面表达式

execution(* com.jsoft.service.impl..(..))

  • execution:声明接下来的是一个表达式
  • *:访问权限
  • com.jsoft.service.impl:包
  • *:类
  • *:方法名
  • (..):参数类型
posted @ 2022-09-21 13:33  (≧∇≦)(≧∇≦)(≧∇≦)  阅读(33)  评论(0)    收藏  举报