目录
一、启动 IoC 容器的方式:
1、Java 环境下启动 IoC 容器:
- ClassPathXmlApplicationContext:从类的根路径下加载配置文件(推荐使用);
- FileSystemXmlApplicationContext:从磁盘路径上加载配置文件;
- AnnotationConfigApplicationContext:纯注解模式下启动 Spring 容器;
2、Web 环境下启动 IoC 容器:
1)从 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>
2)从配置类启动容器
<!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.AnnotationConfigWebApplicationContext
</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>
二、纯 xml 模式
1、bean 对象的创建
具体内容放在例子的注释中。
<!-- 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">
<!-- 实例化Bean的三种方式 -->
<!-- 方式一:使用无参构造函数 -->
<!-- 在默认情况下,它会通过反射调用无参构造函数来创建对象。如果类中没有无参构造函数,将创建失败。 -->
<!-- 配置service对象 -->
<bean id="userService" class="com.lagou.service.impl.TransferServiceImpl"></bean>
<!-- 方式二:使用静态方法创建 -->
<!-- 在实际开发中,很多使用对象实例,并不是直接通过构造函数就可以创建出来的,它可能在创建的过程中会做很多额外的操作。 -->
<!-- 此时会提供一个创建对象的方法,恰好这个方法是 static 修饰的方法,即是此种情况。 -->
<!-- 使用静态方法创建对象的配置方式 -->
<bean id="userService" class="com.lagou.factory.BeanFactory" factory-method="getTransferService"></bean>
<!-- 方式三:使用实例化方法创建 -->
<!--使用实例方法创建对象的配置方式-->
<!-- 此种方式和上面静态方法相比,区别是用于获取对象的方法不再是 static 修饰的了,而是类中的一个普通方法。 -->
<!-- 此种方式比静态方法创建的使用几率要高一些。 -->
<bean id="beanFactory" class="com.lagou.factory.instancemethod.BeanFactory"></bean>
<bean id="transferService" factory-bean="beanFactory" factory-method="getTransferService"></bean>
</beans>
2、对象属性的依赖注入配置
具体内容同样放在例子的注释中。
<!-- 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">
<!-- 方式一:构造函数注入 -->
<!-- 顾名思义,就是利用构造函数实现对类成员的赋值。 -->
<!-- 使用要求是,类中提供的构造函数参数个数必须和配置的参数个数一致,且数据类型匹配。 -->
<!-- 注意的是,当没有无参构造时,则必须提供构造函数参数的注入,否则 Spring 框架会报错。 -->
<bean id="transferDao" class="com.lagou.dao.TransferDaoImpl">
<!-- 构造函数使用 constructor-arg 标签,该标签有如下属性: -->
<!-- name:用于给构造函数中指定名称的参数赋值。 -->
<!-- index:用于给构造函数中指定索引位置的参数赋值。 -->
<!-- value:用于指定基本类型或者 String 类型的数据。 -->
<!-- ref:用于指定其他Bean类型的数据。写的是其他 bean 的唯一标识。 -->
<constructor-arg name="connectionUtils" ref="connectionUtils"/>
<constructor-arg name="name" value="zhangsan"/>
<constructor-arg name="sex" value="1"/>
<constructor-arg name="money" value="100.0"/>
</bean>
<!-- 方式二:set 方法注入 -->
<!-- 顾名思义,就是利用字段的 set 方法实现赋值的注入方式。 -->
<!-- 此种方式在实际开发中是使用最多的注入方式。 -->
<bean id="transferDao" class="com.lagou.dao.TransferDaoImpl">
<!-- 在使用 set 方法注入时,需要使用 property 标签,该标签属性如下: -->
<!-- name:指定注入时调用的 set 方法名称。(不包含 set 这三个字母) -->
<!-- value:指定注入的数据。它支持基本类型和 String 类型。 -->
<!-- ref:指定注入的数据。它支持其他 bean 类型。写的是其他 bean 的唯一标识。 -->
<property name="connectionUtils" ref="connectionUtils"/>
<property name="name" value="zhangsan"/>
<property name="sex" value="1"/>
<property name="money" value="100.0"/>
</bean>
<!-- 方式三:复杂数据类型注入 -->
<!-- 它指的是集合类型数据。集合分为两类,一类是 List 结构(数组结构),一类是 Map 接口(键值对)。 -->
<!-- 注入方式在构造函数和 set 方法中选择,我们的示例选用 set 方法注入。 -->
<bean id="transferDao" class="com.jason.dao.TransferDaoImpl">
<!-- String[] myArray -->
<!-- 注意要点 -->
<!-- 在 List 结构的集合数据注入时,array、list、set 这三个标签通用。-->
<!-- 另外注值的 value 标签内部可以直接写值,也可以使用 <bean/> 标签配置一个对象,或者用 <ref/> 标签引用一个已经配合的 bean 的唯一标识。 -->
<property name="myArray">
<array>
<value>array1</value>
<value>array2</value>
<value>array3</value>
</array>
</property>
<!-- Map<String, String> myMap -->
<!-- 注意要点 -->
<!-- 在 Map 结构的集合数据注入时, -->
<!-- map 标签使用 entry 子标签实现数据注入,entry 标签可以使用 key 和 value 属性指定存入 map 中的数据。 -->
<!-- 使用 value-ref 属性指定已经配置好的 bean 的引用。 -->
<!-- 同时 entry 标签中也可以使用 ref 标签,但是不能使用 bean 标签。 -->
<property name="myMap">
<map>
<entry key="key1" value="value1"/>
<entry key="key2" value="value2"/>
</map>
</property>
<!-- Set<String> mySet -->
<property name="mySet">
<set>
<value>set1</value>
<value>set2</value>
</set>
</property>
<!-- Properties myProperties -->
<!-- 注意要点 -->
<!-- property 标签中不能使用 ref 或者 bean 标签引用对象。 -->
<property name="myProperties">
<props>
<prop key="prop1">value1</prop>
<prop key="prop2">value2</prop>
</props>
</property>
</bean>
</beans>
三、xml 与注解相结合模式
1、注意
- 实际企业开发中,纯 xml 模式使用已经很少了;
- 引入注解功能,不需要引入额外的 jar;
- xml + 注解结合模式,xml 文件依然存在,所以,Spring IoC 容器的启动仍然从加载 xml 开始;
- 哪些 bean 的定义写的 xml 中,哪些 bean 的定义使用注解;
第三方 jar 中的 bean 定义在 xml,比如德鲁伊数据库连接池;
自己开发的 bean 定义使用注解。
2、xml 中标签与注解的对应(IoC)
xml 形式 | 对应的注解形式 |
---|---|
bean 标签 | @Component(""),注解加在类上; bean 的 id 属性内容直接配置在注解后面,如果不配置,默认这个 bean 的 id 为类的类名首字母小写; 另外,针对分层代码开发提供了 @Component 的三个别名 @Controller、@Service、@Repository 分别用于控制层类、服务层类、dao 层类的 bean 定义,这四个注解用法完全一样,只是为了更清晰的区分而已。 |
标签的 scope 属性 | @Scope(“prototype”),默认单例,注解加在类上。 |
标签的 init-method 属性 | @PostConstruct,注解加在方法上,该方法就是初始化后调用的方法。 |
标签的 destory-method 属性 | @PreDestory,注解加在方法上,该方法就是销毁前调用的方法。 |
3、DI 依赖注入的注解实现方式
1)@Autowired (推荐使用)
@Autowired 为 Spring 提供的注解,需要导入包:
org.springframework.beans.factory.annotation.Autowired。
@Autowired 采取的策略为按照类型注入。
public class TransferServiceImpl {
@Autowired
private AccountDao accountDao;
}
当一个类有多个 bean 值的时候,就需要配合着 @Qualifier 使用。
@Qualifier 告诉 Spring 具体去装配哪个对象。
public class TransferServiceImpl {
@Autowired
@Qualifier(name="jdbcAccountDaoImpl")
private AccountDao accountDao;
}
2)@Resource
@Resource 注解由 J2EE 提供,需要导入包 javax.annotation.Resource。
@Resource 默认按照 ByName 自动注入。
public class TransferService {
@Resource
private AccountDao accountDao;
@Resource(name="studentDao")
private StudentDao studentDao;
@Resource(type="TeacherDao")
private TeacherDao teacherDao;
@Resource(name="manDao",type="ManDao")
private ManDao manDao;
}
- 如果同时指定了 name 和 type,则从 Spring 上下文中找到唯一匹配的 bean 进行装配,找不到则抛出异常;
- 如果指定了 name,则从上下文中查找名称(id)匹配的 bean 进行装配,找不到则抛出异常;
- 如果指定了 type,则从上下文中找到类似匹配的唯一 bean 进行装配,找不到或是找到多个, 都会抛出异常;
- 如果既没有指定 name,又没有指定 type,则自动按照 byName 方式进行装配;
3)注意:
@Resource 在 Jdk 11 中已经移除,如果要使用,需要单独引入 jar 包。
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
四、纯注解模式
改造 xml 注解模式,将 xml 中遗留的内容全部以注解的形式迁移出去,最终删除 xml,从 java 配置类启动。
对应注解:
- @Configuration 注解,表示当前类是一个配置类。
- @ComponentScan 注解,替代 context:component-scan。
- @PropertySource,引入外部属性配置文件。
- @Import,引入其他配置类。
- @Value 对变量赋值,可以直接赋值,也可以使用 ${} 读取资源配置文件中的信息。
- @Bean 将方法返回对象加入 Spring IoC 容器。
文章内容输出来源:拉勾教育Java高薪训练营;