第一步:配置扫描路径
首先要明确的是这一步是非常重要的。只有被配置的包下的所有类,添加了注解才能被正确的识别并保存到 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对象中的值,我们会发现获取不到。
属性注入是使用 @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 {
-
- }
- 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依赖注入,有两种实现方式:属性注入和构造注入。
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;
类注解:使用单例模式,注册到容器中;
方法注解:可与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 的生命周期分为以下 5 大部分:
1.实例化 Bean(为 Bean 分配内存空间)
2.设置属性(Bean 注入和装配)
3.Bean 初始化
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=本方法名)