IOC和DI,bean的生命周期,作用域。3种注入方式

IoC

IoC(Inverse of Control:控制反转)是一种设计思想,就是将原本在程序中手动创建对象的控制权,交由Spring框架来管理。 IoC 容器实际上就是个Map(key,value),Map 中存放的是各种对象。

将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注入。这样可以很大程度上简化应用的开发,把应用从复杂的依赖关系中解放出来。 IoC 容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。

1
2
3
4
5
public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationfile.xml");
}
 
//ApplicationContext  上下文   ClassPathXmlApplicationContext加载xml

AnnotationConfigApplicationContext :从一个或多个基于 Java 的配置类中加载 Spring 应用上下文。
AnnotationConfigWebApplicationContext :从一个或多个基于 Java 的配置类中加载 Spring Web 应用上下文。
ClassPathXmlApplicationContext :从类路径下的一个或多个 XML 配置文件中加载上下文定义,把应用上下文的定义文件作为类
资源。
FileSystemXmlapplicationcontext :从文件系统下的一个或多个 XML 配置文件中加载上下文定义。
XmlWebApplicationContext :从 Web 应用下的一个或多个 XML 配置文件中加载上下文定义。

 

Bean的生命周期

0. 扫描xml或者包,遍历bean对象把,java对象包装成beanDeanfine放到3级缓存工厂MAP中

1 . Spring 对 bean 进行实例化;
2 . Spring 将值和 bean 的引用注入到 bean 对应的属性中;
3 .如果 bean 实现了 BeanNameAware 接口, Spring 将 bean 的 ID 传递给 setBean-Name() 方法;
4 .如果 bean 实现了 BeanFactoryAware 接口, Spring 将调用 setBeanFactory() 方法,将 BeanFactory 容器实例传入;
5 .如果 bean 实现了 ApplicationContextAware 接口, Spring 将调用 setApplicationContext() 方法,将 bean 所在的应用上下文的
引用传入进来;
6 .如果 bean 实现了 BeanPostProcessor 接口, Spring 将调用它们的 post-ProcessBeforeInitialization() 方法;
7 .如果 bean 实现了 InitializingBean 接口, Spring 将调用它们的 after-PropertiesSet() 方法。类似地,如果 bean 使用 init-
method 声明了初始化方法,该方法也会被调用;
8 .如果 bean 实现了 BeanPostProcessor 接口, Spring 将调用它们的 post-ProcessAfterInitialization() 方法;
9 .此时, bean 已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁;
10 .如果 bean 实现了 DisposableBean 接口, Spring 将调用它的 destroy() 接口方法。同样,如果 bean 使用 destroy-method 声明了销
毁方法,该方法也会被调用。

   3)、后置处理器;BeanPostProcessor
1)、每一个bean创建完成,都会使用各种后置处理器进行处理;来增强bean的功能;
AutowiredAnnotationBeanPostProcessor:处理自动注入
AnnotationAwareAspectJAutoProxyCreator:来做AOP功能;
xxx....
增强的功能注解:
AsyncAnnotationBeanPostProcessor

 

 

 

3种注入方式:

1、setter注入

1
2
3
4
5
6
7
8
9
10
<!-- 注册userService -->
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
    <!-- 写法一 -->
    <!-- <property name="UserDao" ref="userDaoMyBatis"></property> -->
    <!-- 写法二 -->
    <property name="userDao" ref="userDaoMyBatis"></property>
</bean>
 
<!-- 注册mybatis实现的dao -->
<bean id="userDaoMyBatis" class="com.lyu.spring.dao.impl.UserDaoMyBatis"></bean>
1
2
3
4
5
6
7
8
9
10
11
12
13
public class UserService implements IUserService {
 
    private IUserDao userDao1;
 
    public void setUserDao(IUserDao userDao1) {
        this.userDao1 = userDao1;
    }
 
    public void loginUser() {
        userDao1.loginUser();
    }
 
}

这两种写法都可以,spring会将name值的每个单词首字母转换成大写,然后再在前面拼接上”set”构成一个方法名,然后去对应的类中查找该方法,通过反射调用,实现注入。

2、构造器注入

1
2
3
4
5
6
<!-- 注册userService -->
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
    <constructor-arg ref="userDaoJdbc"></constructor-arg>
</bean>
<!-- 注册jdbc实现的dao -->
<bean id="userDaoJdbc" class="com.lyu.spring.dao.impl.UserDaoJdbc"></bean>

  

1
2
3
4
5
6
7
8
9
10
11
12
13
public class UserService implements IUserService {
 
    private IUserDao userDao;
 
    public UserService(IUserDao userDao) {
        this.userDao = userDao;
    }
 
    public void loginUser() {
        userDao.loginUser();
    }
 
}

3、注解注入  

在介绍注解注入的方式前,先简单了解bean的一个属性autowire,autowire主要有三个属性值:constructor,byName,byType。

    • constructor:通过构造方法进行自动注入,spring会匹配与构造方法参数类型一致的bean进行注入,如果有一个多参数的构造方法,一个只有一个参数的构造方法,在容器中查找到多个匹配多参数构造方法的bean,那么spring会优先将bean注入到多参数的构造方法中。

    • byName:被注入bean的id名必须与set方法后半截匹配,并且id名称的第一个单词首字母必须小写,这一点与手动set注入有点不同。

    • byType:查找所有的set方法,将符合符合参数类型的bean注入。
  • @Autowired:spring注解,默认是以byType的方式去匹配与属性名相同的bean的id,如果没有找到,就通过byName的方式去查找

 

Spring 中的 bean 的作用域有哪些?

  • singleton : 唯一 bean 实例,Spring 中的 bean 默认都是单例的。
  • prototype : 每次请求都会创建一个新的 bean 实例。
  • request : 每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。
  • session : 每一次HTTP请求都会产生一个新的 bean,该bean仅在当前 HTTP session 内有效。
  • global-session: 全局session作用域,仅仅在基于portlet的web应用中才有意义,Spring5已经没有了。Portlet是能够生成语义代码(例如:HTML)片段的小型Java Web插件。它们基于portlet容器,可以像servlet一样处理HTTP请求。但是,与 servlet 不同,每个 portlet 都有不同的会话

posted on   潮流教父孙笑川  阅读(45)  评论(0编辑  收藏  举报

(评论功能已被禁用)
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· winform 绘制太阳,地球,月球 运作规律
· 上周热点回顾(3.3-3.9)

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示