学习自用
目录
前言
Spring 是通过反射来实现注入的
一、什么是依赖注入?
Dependency Injection,是实现 Spring 控制反转思想的技术
在 Spring 中,组件之间的依赖关系
由 Spring 容器(Ioc 容器)在运行期间决定。通俗的说,依赖注入是由容器动态的向某个对象提供它所需要的其他对象
依赖
:对象(组件)和对象(组件)之间的关联关系,如业务层与持久层的关系,业务层调用持久层
注入
:一种数据传递行为,通过注入行为来让对象和对象产生关系,分为以下两种方式
- set 注入
- 构造注入
1.1 目的
① 提升组件重用的频率
② 为系统搭建一个灵活、可扩展的平台
1.2 结果
通过赖注入机制,我们只需要通过简单的配置,无需任何代码就可指定目标需要的资源,便可完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现,降低耦合度。
1.3 理解关键
谁依赖于谁
应用程序依赖于 Spring IOC 容器,即使用者依赖于方法调用方
,如 service 对象依赖于 dao 对象
为什么需要依赖
应用程序需要 IoC 容器来提供目标对象所需要的外部资源
谁注入谁
IoC容器注入应用程序中的某个对象,是应用程序中注入的目标对象所依赖的对象,即Spring 给使用者注入依赖对象
注入了什么
注入目标对象所需要的外部资源
(包括对象、资源、常量数据)
二、Bean 管理
使用
< bean />
标签
<bean id="" class="" name=""> </bean>
2.1 基本属性
1)id
- bean 的唯一标识,具有
唯一性
- 命名规范与 Java 命名规范一致
2)name
- 也是bean的标识,但与 id 不同,不做唯一要求和命名规范
- 如果没有设置name 只设置了 id,那么 name 的值为id的值
- 如果设置name 没有设置 id,也能根据 name 找到对应的 bean
- 如果都设置了,那么只要是 id 或者 name 的值就能知道对应的bean
<?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
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user1" name="user" class="com.fs.pojo.User"> </bean>
</beans>
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = context.getBean("user", User.class);
User user1 = context.getBean("user1", User.class);
System.out.println(user == user1); // true
- 如果都没有设置,则以该 Bean 对应的
全限定类名 + #下标
给 Bean 标识,下标从 0 开始
3)scope
- Bean 作用域
- 默认为单例(singleton):即通过 getBean() 获取这个Bean,不管是获取几次,都是同一个 Bean 实例。
对象在Spring容器创建时创建
。
// Spring容器创建
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml")
- 多例(prototype):每次都是获取的一个全新的 Bean 实例,各不相同。此时对象是在需要用的时候创建,即
调用 getBean() 方法时才会创建
。
2.2 别名
使用 < alias /> 标签,为对应 Bean 对象取别名
<bean class="com.fs.pojo.User" name="user" id="user1">
<property name="monies">
<list>
<ref bean="money3" />
</list>
</property>
</bean>
<alias name="user" alias="xxx"/>
- < alias /> 的 name 属性可以是 < bean /> 中的 id 属性的值,也可以是 < bean /> 中的 name 属性的值
- < alias /> 的 alias 为给对应 < bean /> 取的别名
2.3 生命周期
- init-method
- Bean 初始化方法名
用处
:数据初始化,如创建连接池
- destory-method
- Bean 销毁之前的方法名
作用
:释放资源,如关闭连接池中的连接对象
2.4 实例化
静态工厂方法
Spring
不管理
静态工厂,通过静态工厂方法创建对象
创建一个工厂类,提供一个创建对象的静态方法
/**
* 产生User对象的静态工厂
*/
public class UserStaticFactory {
/**
* 静态工厂方法
* @return User
*/
public static User createUser(){
System.out.println("静态工厂创建user...");
return new User();
}
}
在配置文件中创建对象
<bean id="user3" class="com.fs.factory.UserStaticFactory" factory-method="createUser"> </bean>
注意
- id:创建的
目标对象的标识
- class:是
静态工厂全限定类名
,不是目标对象的 - factory-method:工厂创建对象的静态方法
实例工厂方法
Spring
管理
实例工厂,使用实例工厂方法创建对象
创建一个工厂类,提供一个创建对象的非静态方法
public class UserInstanceFactory {
public User createUser(){
System.out.println("实例工厂创建user...");
return new User();
}
}
配置文件注入实例工厂对象,并创建目标对象
<!-- 把实例工厂对象交给Spring管理-->
<bean id="userInstanceFactory" class="com.fs.factory.UserInstanceFactory"> </bean>
<!-- 创建目标对象 -->
<bean id="user4" class="com.fs.pojo.User" factory-bean="userInstanceFactory" factory-method="createUser"> </bean>
注意
- factory-bean:工厂对象的bean的id
- factory-method:调用创建的对象方法
构造方法
Bean 实例化默认方式,调用目标类的构造方法创建对象
<bean id="userDao" class="com.fs.dao.impl.UserDaoImpl" init-method="init" destroy-method="close"></bean>
2.5 自动装配
使用
autowire
属性
spring 根据 Bean 的依赖,自动给属性注入值
通俗点说,就是开启了autowire属性之后,一个bean依赖的其他bean不再需要手动写,Spring 会根据自动装配的模式找到配置文件中的对应的目标 bean 对象,并自动注入
- autowrie
- 默认不开启
- 模式
- 根据类型:byType, 如果有多个相同的类型,会抛异常
- 根据
set方法之后的字符
名字:byName
public class Person {
private Money m;
public void setMoney4(Money m) {
this.m = m;
}
public Money getM() {
return m;
}
@Override
public String toString() {
return "Person{" +
"m=" + m +
'}';
}
}
<bean id="money4" class="com.fs.pojo.Money">
<property name="num" value="100"/>
</bean>
<bean id="person" class="com.fs.pojo.Person" autowire="byName"> </bean>
三、构造注入
通过
< constructor-arg >
标签进行构造器参数注入
标签属性说明
● name:构造方法参数名
● type:属性类型
● index:参数索引(从0开始)
● ref:当属性是对象时,使用 ref 来引用该对象 bean 的值
// lombok注解:Set、Get、toString方法等
@Data
// lombok注解:有参构造
@AllArgsConstructor
// lombok注解:无参构造
@NoArgsConstructor
public class User {
private String name;
private Dog dog;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dog {
private String name;
}
3.1 使用 name + value / ref
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dog" class="com.fs.pojo.Dog">
<constructor-arg name="name" value="旺财"/>
</bean>
<bean id="user" class="com.fs.pojo.User">
<constructor-arg name="name" value="张三"/>
<constructor-arg name="dog" ref="dog"/>
</bean>
</beans>
3.2 使用 index + value /ref
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dog" class="com.fs.pojo.Dog">
<constructor-arg name="name" value="旺财"/>
</bean>
<bean id="user" class="com.fs.pojo.User">
<constructor-arg index="0" value="张三"/>
<constructor-arg index="1" ref="dog"/>
</bean>
</beans>
3.3 使用 value /ref
会自动进行类型判断
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dog" class="com.fs.pojo.Dog">
<constructor-arg name="name" value="旺财"/>
</bean>
<bean id="user" class="com.fs.pojo.User">
<constructor-arg value="张三"/>
<constructor-arg ref="dog"/>
</bean>
</beans>
这种方式需要注意
- 当注入的对象有相同类型的属性时,注入的值会根据配置文件中的顺序进行注入
- 反之,若注入的对象的属性不存在相同类型时,没有顺序要求,Spring 会自动对属性进行类型判断
四、Set 注入
set 注入基于属性的 set 方法实现,底层通过反射机制调用属性对应的set方法进行属性赋值
- 属性是基本数据类型,使用 value 注入值
- 属性是其他 bean 对象时,使用 ref 注入值
<bean id="user" class="com.fs.pojo.User">
<property name="sex" value="男"/>
<property name="money" ref="money1"/>
</bean>
4.1 < p />
可以使用 < P /> 命名空间进行简化 set 注入
注意
:需要在配置文件头部加入p的约束
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
<!-- 需要在配置文件头部加入p的约束 -->
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.fs.pojo.User" p:sex="男" p:money-ref="money1">
<!--<property name="sex" value="男"/>-->
<!--<property name="money" ref="money1"/>-->
</bean>
</beans>
4.2 数组属性
语法
< bean id=“” class=“”>
< property name=“属性名”>
< array >
< value >值</ value >
< /array >
< /property>
< /bean>
<bean id="user" class="com.fs.pojo.User">
<property name="属性名">
<array>
<value>张三</value>
<value>李四</value>
</array>
</propery>
</bean>
4.3 List 属性
元素有序
,即按照赋值的顺序注入到 List 集合中
语法
< bean id=“” class=“”>
< property name=“属性名”>
< list >
< value >值</ value >
< /list >
< /property>
< /bean>
当 List 的元素是普通类型
时
<bean id="user" class="com.fs.pojo.User">
<property name="属性名">
<list>
<value>张三</value>
<value>李四</value>
</list>
</propery>
</bean>
当 List 的元素是其他 bean
时
<bean id="money1" class="com.fs.pojo.Money">
<property name="num" value="100"/>
</bean>
<bean id="money2" class="com.fs.pojo.Money">
<property name="num" value="200"/>
</bean>
<bean class="com.fs.pojo.User">
<property name="monies">
<list>
<ref bean="money1" />
<ref bean="money2" />
</list>
</property>
</bean>
4.4 Set 集合属性
自动
去重
,且无序
排列
语法
< bean id=“” class=“”>
< property name=“属性名”>
< set >
< value >值</ value >
< /set >
< /property>
< /bean>
<bean id="user" class="com.fs.pojo.User">
<property name="属性名">
<set>
<value>张三</value>
<value>李四</value>
</set>
</propery>
</bean>
4.4 Map 属性
语法
< bean id=“” class=“”>
< property name=“属性名”>
< map >
< entry key=“” value=“” />
< /map >
< /property>
< /bean>
<bean id="user" class="com.fs.pojo.User">
<property name="属性名">
<map>
<entry key="zs" value="张三"></entry>
</map>
</propery>
</bean>
4.5 Properties 属性
继承自 HashMap
,key 与 value 都是 String 类型
语法
< bean id=“” class=“”>
< property name=“属性名”>
< props >
< prop key=“zs” value=“张三” />
< /props >
< /property>
< /bean>
<bean id="user" class="com.fs.pojo.User">
<property name="属性名">
<props>
<prop key="zs" value="张三"></prop>
</props>
</propery>
</bean>