依赖注入
@Autowired注入
- 注入方式:
1. 构造方法注入,若类中只有一个构造方法,则该注解可省略 2. setter注入 3. 字段注入
- 注入规则:
该注解是Spring框架提供的注解,默认按照数据类型注入Bean对象 - 若没有匹配的数据类型,直接注入失败 - 若该类型对应的Bean对象有多个时,此时会产生歧义 -产生歧义时,会自动根据beanId会查找是否有对应的Bean对象,若有则注入 -使用@Qualifier(name)指定BeanId/BeanName
@Resource注入
-
注入规则:
默认按照beanId注入,若找不到匹配的BeanId,则回退到根据数据类型注入 @Resource private UserDao dao;
-
注入方式:注意不支持构造方法注入
1. set方法注入 注意:setAccountDao(...)从方法名中提取BeanId,为set后的名称首字母小写 2. 字段注入 注意: 1. @Resource(name="....")可以通过name属性指定BeanId 2. @Resource注解若没有指定name,则默认是先按照name查找,找不到则回退到类型查找;若指定了name,则只根据name查找,若找不到,则直接报错
https://gitee.com/huadahua/spring-2205.git
Stereotype注解和Meta注解
- stereotype注解:合成注解/组合注解
@Controller @Service @Repository。。。。。均为合成注解 合成注解:由其他若干个注解组合而成的注解
- Meta注解:元注解
定义:能够作用在其他注解上方的注解,成为元注解 注意:一个注解可能既是合成注解,同时也可能是元注解
Bean的生命周期
-
Bean的生命周期
是指Bean对象从创建到销毁的过程
-
@PostConstruct和@PreDestory
- 前提:使用以上注解定义自定义操作,要求方法必须无参且返回void
- @PostConstruct:
- 该注解作用于方法上方,用于定义自定义初始化操作,该方法会在Bean初始化过程中被调用 - 作用时机:在Bean的初始化过程中,该注解标记的方法会在setter注入之后被调用
- @PreDestory
- 该注解作用于方法上方,用于定义自定义操作,该方法会在Bean销毁之前被调用 - 注意点: 1. 只有容器正常关闭时才会调用该注解标记的方法,若容器是意外关闭或强制关闭,则不会调用该注解标记的方法 2. System.exit(..)是强制关闭JVM,而JVM关闭时会自动关闭Spring容器,此时Spring容器并不是强制/意外终止,而是正常结束,所以@PreDestory的方法会被调用
- 通过@Bean的属性在Bean初始化和销毁前执行自定义操作
显示配置Bean时,可以通过添加@Bean的属性initMethod和destoryMethod来指定对应的方法。效果和@PostConstruct,@PreDestory是一样的 @Bean(initMethod="populateCache", destroyMethod="flushCache") 注意:两种方式选择问题 1. 若是自定义的类,则可以通过隐式配置Bean,此时可以使用@PostConstruct和@PreDestory 2. 若配置的不是自己写的类,则可以通过显示配置Bean,此时可以使用属性initMethod和destoryMethod
- 构造注入,setter注入,字段注入的执行顺序
构造注入-->字段注入-->setter注入
Bean的生命周期
初始化:
-
加载并后处理Bean的定义
加载Bean的定义: 检测@Bean注解和组件类注解,将Bean的定义加载到BeanFactory中(ApplicationContext就是一个BeanFactory),在BeanFactory中,bean的id和类型都会被索引 后处理Bean的定义: -- 调用BFPP BeanFactoryPostProcessor在这个节点会被调用,用于修改Bean定义的属性(比如作用域),这个阶段结束,Bean定义加载结束,即将开始实例化Bean - Spring中已经定义好了一些BFPP的实现类,用于处理一些操作,常见的有: 从属性文件读取属性,修改Bean的作用域 -PropertySourcesPlaceholderConfigurer,该类实现了BFPP接口,用于完成读取属性
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CplLf4OP-1658718542639)(D:\Spring认证\笔记\2205\week02\加载并后处理Bean定义.png)]
-
实例化
1. 查找Bean的依赖 2. 实例化Bean 3. 构造方法注入 4. setter注入
-
初始化
会调用初始化器,可以在初始化之前和之后添加操作,通过接口BeanPostProcessor(BPP)完成--该阶段叫做Bean的后处理过程 注意:BPP中重写两个方法后,两个方法会在每个Bean的初始化器之前和之后都调用 BPP的应用:若想在所有的Bean初始化之前和之后统一的执行一些操作,此时可以通过接口BPP完成。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OT4o7ODZ-1658718542643)(D:\Spring认证\笔记\2205\week02\实例化以及初始化.png)]
AOP:
-
定义:
Aop是面向切面编程,用于实现关注点代码和业务代码的分离解耦的,可以提高代码的可维护性和可扩展性
-
Spring中AOP的使用
1. 导入aspectjweaver依赖 <dependency> <groupId>aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.5.4</version> </dependency> 2. 定义切面类,类中定义通知以及切入点表达式 3. 配置类上方添加注解@EnableAspectJAutoProxy启动aop
-
代码实现
- 业务类中的业务方法:
@Component public class MyAopBean { public void addUser(){ System.err.println("添加用户开始"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.err.println("添加用户完成"); } public void findUserByName(){ System.err.println("查询用户开始"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.err.println("查询用户结束"); } public void deleteUser(){ System.err.println("删除用户开始"); try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } System.err.println("删除用户结束"); } }
- 切面类
@Aspect @Component public class TimeAspect { @Around("execution(* cn.tedu..aop.*.*(..))") public void getTime(ProceedingJoinPoint joinPoint) throws Throwable { //关注点代码 long t1 = System.currentTimeMillis(); //业务代码执行 joinPoint.proceed(); long t2 = System.currentTimeMillis(); System.err.println(joinPoint.toShortString()+"耗时:"+(t2-t1)+"毫秒"); } }
- 测试类
public class AopTest { public static void main(String[] args) { ApplicationContext context = SpringApplication.run(Week02Config.class); MyAopBean bean = context.getBean(MyAopBean.class); bean.addUser(); bean.deleteUser(); bean.findUserByName(); } }