一、存储Bean对象
第一步:配置扫描路径
首先要明确的是这一步是非常重要的。只有被配置的包下的所有类,添加了注解才能被正确的识别并保存到 Spring 中。
//ApplicationContext是Spring容器的顶级接口
//AnnotationConfigApplicationContext是其中一个实现类,
// 作用:
// 1. 扫描指定包路径下,使用Spring框架注解的类。
// 2. 注册这些类到容器中=》框架帮助我们new对象,及注入队象依赖关系
ApplicationContext context
= new AnnotationConfigApplicationContext("org.example");
第二步:添加注解存储Bean对象
想要将对象存储在 Spring 中,有两种注解类型可以实现:
1. 类注解:@Controller、@Service、@Repository、@Component、@Configuration。
2. 方法注解:@Bean
我们还要认识的是:方法注解@Bean
这块要注意的是方法注解要配合类注解使用。如果我们单单使用Bean注解的话,要想获取Bean对象中的值,我们会发现获取不到。
二、获取Bean对象(装配/注入)
2.1 属性注入
属性注入是使用 @Autowired 实现的,将 Service 类注入到 Controller 类中
分层的依赖关系:
package org.example.controller;
import lombok.Data;
import org.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
@Data// lombok注解:自动生成Getter、Setter、hashCode、equals、toString
public class UserController {
//使用String容器,帮助我们将Bean容器中的
@Autowired
private UserService userService;
}
--------------------------------------------------------------------------------
package org.example.service;
import lombok.Data;
import org.example.mapper.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
@Data
public class UserService {
@Autowired
private UserRepository userRepository;
}
--------------------------------------------------------------------------------
package org.example.mapper;
import org.springframework.stereotype.Repository;
@Repository
public class UserRepository {
}
2.2 构造注入
package org.example.service;
import lombok.Data;
import org.example.mapper.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
@Data
public class UserService {
// @Autowired
private UserRepository userRepository;
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
构造注入和属性注入是一样的。本质是将UserService注册到容器中。
DI依赖注入,有两种实现方式:属性注入和构造注入。
2.3 @Resource:另一种注入关键字
1. @Autowried 和 @Resource实现的效果是一样的。
@Autowired 和 @Resource 的区别:
- 出身不同:@Autowired 来自于 Spring,而 @Resource 来自于 JDK 的注解;
- 使用时设置的参数不同:相比于 @Autowired 来说,@Resource 支持更多的参数设置,例如name 设置,根据名称获取 Bean。
一个类型,多个bean注入的方式
//1. 使用变量名
@Autowired
private Bean对象2 testBean2_1;
//2. 使用注解
@Autowired
@Qualifier("testBean2_1")
private Bean对象2 bean对象2_1;
// 3.
@Resource(name = "testBean2_2")
private Bean对象2 bean对象2_2;
三、Bean的作用域
类注解:使用单例模式,注册到容器中;
方法注解:可与i注册一个类型,多种实例对象。
如果只有一个实例对象,在两个地方,希望有不同的属性;
解决方法:定义两个实例对象,分别拥有不同的属性,
方法注解:@Bean定义多个方法来注册同类型多个Bean实例;
类注解:就需要通过修改作用域来实现这个功能;
这是就使用@Scope();
@Scope("singleton");//默认还是单例
bean1=org.example.model.Bean对象1@33aeca0b, bean2=org.example.model.Bean对象1@33aeca0b
@Scope("prototype");//每次对该作用域下的Bean的请求都会创建新的实例
bean1=org.example.model.Bean对象1@18cebaa5, bean2=org.example.model.Bean对象1@463b4ac8
四、Bean的生命周期
Bean 的生命周期分为以下 5 大部分:
1.实例化 Bean(为 Bean 分配内存空间)
2.设置属性(Bean 注入和装配)
3.Bean 初始化
- 实现了各种 Aware 通知的方法,如 BeanNameAware、BeanFactoryAware、ApplicationContextAware 的接口方法;
- 执行 BeanPostProcessor 初始化前置方法;
- 执行 @PostConstruct 初始化方法,依赖注入操作之后被执行;
- 执行自己指定的 init-method 方法(如果有指定的话);
- 执行 BeanPostProcessor 初始化后置方法。
4.使用 Bean
5.销毁 Bean
销毁bean的各种方法,如 @PreDestroy、DisposableBean 接口方法、destroy-method。
1,2,3步骤3完成,才算Bean注册成功。
创建好对象;依赖注入(属性初始化);其他初始化内容;把Bean对象放入容器中。
步骤一类似于:new 对象
步骤二类似于:依赖注入:属性赋值
步骤三类似于:表示bean要初始化的内容很多,才能使用
实例化和初始化的区别
实例化和属性设置是 Java 级别的系统“事件”,其操作过程不可人工干预和修改;而初始化是给开发者提供的,可以在实例化之后,类加载完成之前进行自定义“事件”处理。
package org.lifecycle.model;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
//@Service
public class MyBean implements BeanNameAware,
BeanFactoryAware,
ApplicationContextAware,
InitializingBean,
DisposableBean {
public MyBean() {
System.out.println("Bean生命周期方法");
}
@Override
public void setBeanName(String s) {
System.out.println("BeanNameAware接口生命周期方法");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("BeanFactoryAware接口生命周期方法");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("ApplicationContextAware接口生命周期方法");
}
@PostConstruct
public void 初始化方法1() {
System.out.println("Bean初始化方法:@PostConstruct");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Bean初始化方法:@Bean(initMethod=本方法名)");
}
public void 初始化方法2() {
System.out.println("Bean初始化方法:InitializingBean");
}
@PreDestroy
public void 销毁方法1() {
System.out.println("Bean的销毁方法:@PreDestroy");
}
@Override
public void destroy() throws Exception {
System.out.println("Bean的销毁方法:DisposableBean");
}
public void 销毁方法2() {
System.out.println("Bean的销毁方法:@Bean(initMethod=本方法名)");
}
}
---------------------------------------------------------------------------------
package org.lifecycle.config;
import org.lifecycle.model.MyBean;
import org.omg.CORBA.PUBLIC_MEMBER;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class LifecycleConfig implements BeanPostProcessor {
@Bean(initMethod = "初始化方法2",destroyMethod = "销毁方法2")
public MyBean bean() {
return new MyBean();
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor生命周期方法:初始化前置方法");
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor生命周期方法:初始化后置方法");
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
----------------------------------------------------------------------------------------
public static void main(String[] args) {
AnnotationConfigApplicationContext context
= new AnnotationConfigApplicationContext("org.lifecycle");
context.close();
}
执行结果:
Bean生命周期方法
BeanNameAware接口生命周期方法
BeanFactoryAware接口生命周期方法
ApplicationContextAware接口生命周期方法
BeanPostProcessor生命周期方法:初始化前置方法
Bean初始化方法:@PostConstruct
Bean初始化方法:@Bean(initMethod=本方法名)
Bean初始化方法:InitializingBean
BeanPostProcessor生命周期方法:初始化后置方法
12:15:38.792 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@e73f9ac, started on Wed Jul 20 12:15:38 CST 2022
Bean的销毁方法:@PreDestroy
Bean的销毁方法:DisposableBean
Bean的销毁方法:@Bean(initMethod=本方法名)
本文详细介绍了Spring如何存储和获取Bean对象,包括使用注解存储Bean,如@Controller、@Service等,以及通过@Autowired和@Resource进行属性和构造注入。同时,讨论了Bean的作用域,如singleton和prototype,并解析了Bean的生命周期,从实例化、属性设置到初始化和销毁的全过程。


1630

被折叠的 条评论
为什么被折叠?



