当前位置: 移动技术网 > IT编程>开发语言>Java > Java开发中Spring IOC容器的使用详解

Java开发中Spring IOC容器的使用详解

2020年08月01日  | 移动技术网IT编程  | 我要评论
详解Spring IOC文章内容输出来源:拉勾教育Java高薪训练营看前如果没有基础的话建议先看上一篇手动实现IOC和AOP思路Spring IoC基础Spring IoC有两个重要的概念:beans.xml:定义实例化对象的类全限定类名以及类之间依赖关系的描述。BeanFactory:IOC容器,通过反射技术来实例化对象并维护对象之间的依赖关系。1.BeanFactory与ApplicationContext区别BeanFactory是Spring框架中IoC容器的顶层接口,它只是用来

详解Spring IOC



文章内容输出来源:拉勾教育Java高薪训练营


看前如果没有基础的话建议先看上一篇手动实现IOC和AOP思路

Spring IoC基础

Spring IoC有两个重要的概念:

  1. beans.xml:定义实例化对象的类全限定类名以及类之间依赖关系的描述。
  2. BeanFactory:IOC容器,通过反射技术来实例化对象并维护对象之间的依赖关系。

1.BeanFactory与ApplicationContext区别

BeanFactory是Spring框架中IoC容器的顶层接口,它只是用来定义一些基础功能,定义一些基础规范,而 ApplicationContext是它的一个子接口,所以ApplicationContext是具备BeanFactory提供的全部功能的。

通常,我们称BeanFactory为SpringIOC的基础容器,ApplicationContext是容器的高级接口,比 BeanFactory要拥有更多的功能,比如说国际化支持和资源访问(xml,java配置类)等等

启动IoC容器的方式
  • Java环境下启动IoC容器

    • ClassPathXmlApplicationContext:从类的根路径下加载配置文件(推荐使用)
    • FileSystemXmlApplicationContext:从磁盘路径上加载配置文件
    • AnnotationConfigApplicationContext:纯注解模式下启动Spring容器
  • Web环境下启动IoC容器 从xml启动容器

    • 从xml启动容器
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <!--配置Spring ioc容器的配置文件--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <!--使用监听器启动Spring的IOC容器--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app> 
  • 从配置类启动容器
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <!--告诉ContextloaderListener知道我们使用注解的方式启动ioc容器--> <context-param> <param-name>contextClass</param-name> <param- value>org.springframework.web.context.support.AnnotationConfigWebAppli cationContext</param-value> </context-param> <!--配置启动类的全限定类名--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>com.lagou.edu.SpringConfig</param-value> </context-param> <!--使用监听器启动Spring的IOC容器--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app> 

2. 纯xml模式

2.1 xml 文件头
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd"> 
2.2 实例化Bean的三种方式
  • 方式一:使用无参构造

在默认情况下,它会通过反射调用无参构造函数来创建对象。如果类中没有无参构造函数,将创建失败。

<!--配置service对象--> <bean id="userService" class="com.lagou.service.impl.TransferServiceImpl"> </bean> 
  • 方法二:使用静态方法构建
//Java代码实例 public class BeanFactory{ private static UserService userService; public static UserService getTransferService(){ return userService; } } 
<!--使用静态方法创建对象的配置方式--> <bean id="userService" class="com.lagou.factory.BeanFactory" factory-method="getTransferService"></bean> 
  • 方法三:使用实例化方法构建
//Java代码实例 public class BeanFactory{ private UserService userService; public UserService getTransferService(){ return userService; } } 
<!--使用实例方法创建对象的配置方式--> <bean id="beanFactory" class="com.lagou.factory.instancemethod.BeanFactory"></bean> <bean id="transferService" factory-bean="beanFactory" factory-method="getTransferService"></bean> 
2.3 Bean的作用范围及生命周期
  • 作用范围

在spring框架管理Bean对象的创建时,Bean对象默认都是单例的,但是它支持配置的方式改变作用范围。

作用范围官方提供的说明如下图:

在上图中提供的这些选项中,我们实际开发中用到最多的作用范围就是**singleton(单例模式)和 prototype(**原型模式,也叫多例模式)。

配置方式参考下面的代码:

 <!--scope属性就是描述作用范围--> <bean id="transferService" class="com.lagou.service.impl.TransferServiceImpl" scope="singleton"> </bean> 
  • 生命周期

    • 单例模式:singleton

      单例模式的bean对象生命周期与容器相同。

    • 多例模式:prototype

      多例模式的bean对象,spring框架只负责创建,不负责销毁。

2.4 Bean标签属性

在基于xml的IoC配置中,bean标签是最基础的标签。它表示了IoC容器中的一个对象。换句话 说,如果一个对象想让spring管理,在XML的配置中都需要使用此标签配置,Bean标签的属性如下:

属性 效果
id 用于给bean提供一个唯一标识。在一个标签内部,标识必须唯一。
class 用于指定创建Bean对象的全限定类名。
name 用于给bean提供一个或多个名称。多个名称用空格分隔。
factory-bean 用于指定创建当前bean对象的工厂bean的唯一标识。当指定了此属性之后, class属性失效。
factory-method 用于指定创建当前bean对象的工厂方法,如配合factory-bean属性使用, 则class属性失效。如配合class属性使用,则方法必须是static的。
scope 用于指定bean对象的作用范围。通常情况下就是singleton。当要用到多例模式时, 可以配置为prototype。
init-method 用于指定bean对象的初始化方法,此方法会在bean对象装配后调用。必须是 一个无参方法。
destory-method 用于指定bean对象的销毁方法,此方法会在bean对象销毁前执行。它只 能为scope是singleton时起作用。
2.5 DI 依赖注入的xml配置
  • 依赖注入分类

    • 按照注入的方式分类

      • 构造函数注入:顾名思义,就是利用带参构造函数实现对类成员的数据赋值。

        // 使用要求是,类中提供的构造函数参数个数必须和配置的参数个数一致,且数据类型匹配。同时需要注意的是,当没有无参构造时,则必须提供构造函数参数的注入,否则Spring框架会报错。 public class JdbcAccountDaoImpl implements AccountDao{ private ConnectionUtils connectionUtils; private String name; private int sex; private float money; public JdbcAccountDaoImpl(ConnectionUtils connectionUtils, String name, int sex, float money){ this.connectionUtils = connectionUtils; this.name = name; this.sex = sex; this.money = money; } } //xml name:用于给构造函数中指定名称的参数赋值。index:用于给构造函数中指定索引位置的参数赋值。 // 		value:用于指定基本类型或者String类型的数据。ref:用于指定其他Bean类型的数据。写的是其他bean的唯一标识。 <bean id="accountDao" class="com.lagou.edu.dao.impl.JdbcAccountDaoImpl"> <constructor-arg name="connectionUtils" ref="connectionUtils"/> <constructor-arg name="name" value="zhangsan"/> <constructor-arg name="sex" value="1"/> <constructor-arg name="money" value="100.6"/> </bean> 
      • set方法注入:它是通过类成员的set方法实现数据的注入。(使用最多的)

        //利用字段的set方法实现赋值的注入方式。此种方式在实际开发中是使用最多的注 入方式。 public class JdbcAccountDaoImpl implements AccountDao{ private ConnectionUtils connectionUtils; private String name; private int sex; private float money; public void setConnectionUtils(ConnectionUtils connectionUtils){ this.ConnectionUtils = connectionUtils; } public void setName(String name){ this.name = name; } ... } <bean id="accountDao" class="com.lagou.edu.dao.impl.JdbcAccountDaoImpl"> <property name="connectionUtils" ref="connectionUtils"/> <property name="name" value="zhangsan"/> <property name="sex" value="1"/> <property name="money" value="100.6"/> </bean> 
    • 按照注入的数据类型分类

      • 基本类型和String:name-value
      • 其他Bean类型:name-ref
      • 复杂类型(集合类型)
      <!--set注入复杂数据类型--> <property name="myArray"> <array> <value>array1</value> <value>array2</value> <value>array3</value> </array> </property> <property name="myMap"> <map> <entry key="key1" value="value1"/> <entry key="key2" value="value2"/> <entry key="key3" value="value3"/> </map> </property> <property name="mySet"> <set> <value>set1</value> <value>set2</value> <value>set3</value> </set> </property> <property name="myProperties"> <props> <prop>prop1</prop> <prop>prop2</prop> <prop>prop3</prop> </props> </property> 

      在相同结构的集合数据注入时,内部标签是通用的,例如array , list , set 这三个标签通用。

3. xml与注解相结合模式

1)实际企业开发中,纯xml模式使用已经很少了

2)引入注解功能,不需要引入额外的jar

3)xml+注解结合模式,xml文件依然存在,所以,spring IOC容器的启动仍然从加载xml开始

4)哪些bean的定义写在xml中,哪些bean的定义使用注解

  • 第三方jar中的bean定义在xml,比如德鲁伊数据库连接池

  • 自己开发的bean定义使用注解

3.1 xml中标签与注解的对应(IoC)
xml形式 对应的注解形式
标签 @Component(“accountDao”),注解加在类上 bean的id属性内容直接配置在注解后面如果不配置,默认定义个这个bean的id为类 的类名首字母小写; 另外,针对分层代码开发提供了@Componenet的三种别名@Controller、 @Service、@Repository分别用于控制层类、服务层类、dao层类的bean定义,这 四个注解的用法完全一样,只是为了更清晰的区分而已
标签的 scope属性 @Scope(“prototype”),默认单例,注解加在类上
标签的init- method 属性 @PostConstruct,注解加在方法上,该方法就是初始化后调用的方法
标签的destory- method 属性 @PreDestory,注解加在方法上,该方法就是销毁前调用的方法
3.2 DI 依赖注入到的注解实现方式
  • @Autowired(推荐使用)
public class TransferServiceImpl { @Autowired private AccountDao accountDao; } public class TransferServiceImpl { @Autowired @Qualifier(name="jdbcAccountDaoImpl") private AccountDao accountDao; } 

如上第一个代码所示,这样装配回去spring容器中找到类型为AccountDao的类,然后将其注入进来。

这样会产生一个问题,当一个类型有多个bean值的时候,会造成无法选择具体注入哪一个的情况, 这个时候我们需要配合着@Qualifier使用。

@Qualifier告诉Spring具体去装配哪个对象。

  • @Resource

@Resource 在 Jdk 11中已经移除,如果要使用,需要单独引入jar包。

且不常用,有需要的可以自行了解。

<dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.3.2</version> </dependency> 

4. 纯注解模式

改造为纯注解模式,将xml中遗留的内容全部以注解的形式迁移出去,最终删除xml,从Java配置类启动对应注解

//xml中遗留的内容,目的就是将其全部以注解的形式迁移出去,最终删除xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd "> <!--开启注解扫描,base-package指定扫描的包路径--> <context:component-scan base-package="com.lagou.edu"/> <!--引入外部资源文件--> <context:property-placeholder location="classpath:jdbc.properties"/> <!--第三方jar中的bean定义在xml中--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> </beans> 

@Configuration 注解,表名当前类是一个配置类

@ComponentScan 注解,替代 context:component-scan

@PropertySource,引入外部属性配置文件

@Import 引入其他配置类

@Value 对变量赋值,可以直接赋值,也可以使用 ${} 读取资源配置文件中的信息 @Bean 将方法返回对象加入 SpringIOC 容器

@Configuration @ComponentScan({"com.lagou.edu"}) @PropertySource({"classpath:jdbc.properties"}) /*@Import()*/ public class SpringConfig { @Value("${jdbc.driver}") private String driverClassName; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; @Bean("dataSource") public DataSource createDataSource(){ DruidDataSource druidDataSource = new DruidDataSource(); druidDataSource.setDriverClassName(driverClassName); druidDataSource.setUrl(url); druidDataSource.setUsername(username); druidDataSource.setPassword(password); return druidDataSource; } } 

这样,我们就成功将xml中的内容全部用注解的形式迁移出去了。

本文地址:https://blog.csdn.net/weixin_43871142/article/details/108248877

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网