IDEA快捷键 ctrl+[up]+o 清除无用的包
spring优势
1.不用在代码中new对象。 在代码种new对象,对象就是固定的,难以修改。 而在容器赋值,则随时可以修改。
2.实现解耦合。 如果mysql改用oracle,只需要再写一个实现类,然后在配置文件中新建一个对象的即可。
- spring底层通过【反射机制】实现
IoC控制反转
1.概念
- Ioc是一种思想,具体的技术实现是通过DI实现
- 容器(Spring)来创建对象。 不需要手动写Java代码创建对象
- bean对象指的就是java对象
- 和servlet的配置文件一样,什么class能够自动被容器spring创建对象 ,也需要在一个配置文件beans.xml中声明
- spring创建对象时间:是在spring容器创建后会自动 创建配置文件中的全部class对象
- spring创建对象默认调用 类的无参数构造方法
2.创建一个spring项目
配置文件的位置:classes路径里面
3.DI 注入
- 设值注入两种方式:xml,
- 给属性赋值必须通过setter方法。 只要类有set方法,就能调用和赋值。不管这个类是自定义的还是已经有的。
1)XML文件
1.1 两种注入方式:
a.设值注入
普通类型
引用类型 先声明School对象,再ref引用
b.构造注入
1.2 引用类型的自动注入
a. by name按名称注入
b. by type
by type中,在xml配置文件中,必须只能有一个符合条件的。
1.3 多个配置文件
- 把不同的模块放在不同的配置文件中
- 有一个total文件,管理其他配置文件
- java中的读取read文件
如果要用通配符,文件必须放在一个目录中
2)基于注解的DI
- java代码 定义类+注解
- 配置文件 中写组件扫描器
- java代码 test
- 组件扫描器 配置文件中写
注解:
- component注解,java中写
- Repository, Service, Controller注解除了Component的功能外,还有 对象分层 的功能
- 当既不是dao, service, controller类时,使用Component
- value 赋值,不需要Setter, 写在属性上方或方法上方,一般写在 属性的上方。
- Autowired 对引用类型 自动装配对象, 默认按照type装配
- 与Qualifier同时使用, 按name装配
- Resource来自于jdk
动态代理
- 作用:实现功能增强
- 在不需要修改原来代码的前提下,给目标类增加额外的功能,可以保证原代码专注于业务逻辑
- 使用了jdk的proxy代理动力节点Spring框架教程【IDEA版】-Spring框架从入门到精通_哔哩哔哩_bilibili
- 两种实现方式
(1)jdk动态代理,使用jdk中的Proxy,Method,InvocaitonHanderl创建代理对象。
jdk动态代理要求目标类必须实现接口
(2) cglib动态代理:第三方的工具库,创建代理对象,原理是继承。 通过继承目标类,创建子类。子类就是代理对象。 要求目标类不能是final的, 方法也不能是final的
AOP (Aspect Orient Programming) 面向切面编程
- 底层是动态代理
- 实质是一个规范/标准,动态代理的规范化,把动态代理的实现步骤、方式都定义好
- 提供一个统一的方式,实现标准化
- 切面aspect:给目标类增加的功能, 一般是 非业务方法
- 两种代理方式:jdk代理、cglib代理 。 有接口默认jdk代理、无接口默认cglib代理,有接口也可以设置成cglib代理。
- 框架:spring 和aspectj(使用较多,且能通过spring实现)
1.aspectj步骤:
重点4,5步
切面类
- 可以加多个切面方法
- 如果execution后面方法的表达式出错,则自动生成代理器扫描时找不到代理,就不会执行aspect方法,只执行业务方法
配置文件
1)先声明两个对象 2) 声明自动生成代理器时,会启用aspectj框架,去扫描对象的注解,利用注解标识身份。
测试类
- 这里强转成 接口类型
2.JoinPoint
- 所有类型通知都可以用
- 在切面功能中,如果需要用到业务方法的执行信息,如业务方法的形参、方法名等
- JoinPoint 是作为参数,传入到切面方法中,实际上就是代表目标方法Method
- 必须是第一个参数
3.一些通知
1.Before前置通知
- 目标方法之前执行
2.AfterReturning后置通知
- 在目标方法执行之后再执行
- 可以拿到目标方法执行返回的结果
- 并针对结果做判断,编写相应的代码
- returning
- 修改返回值参数res不会对 真正的业务返回值结果 产生影响? 因为先执行目标方法(),将目标方法的结果传入到后置通知(),后置通知()的结果不会影响目标方法()的结果。
3.Around环绕通知
- 功能最强
- 经常做事务,目标方法之前开启事务,执行目标方法啊,目标方法之后提交事务
- 在方法前后都能增加功能
- ProceedingJoinPoint 继承了JoinPoint,能够获得目标方法的信息
- 参数pjp实际上等于 代理模块中的Method,就是要执行的目标方法
- pjp.proceeding()执行目标方法
- 能够修改目标方法的返回结果。 代理器执行doFirst(),实际上是执行myAround环绕通知(),因此环绕通知中结果是什么,最后就返回什么。
4.AfterThrowing异常通知
- 抛出异常用
- 相当于try{ 业务方法() } catch{ 异常通知() }
5.After最终通知
- 无论代码是否有异常,总会被执行
- 相当于try{ 业务方法() } catch{ } finally{ 最终通知() }
4.切入点表达式
- 定义和管理切入点,辅助作用
- mypt私有的,因为不需要被外界使用