# IOC-2
# 依赖注入
依赖注入,即为前面说的 DI(Dependency Injection)
依赖:指 Bean 对象的创建依赖于容器 。Bean 对象的依赖资源。
注入:指 Bean 对象所依赖的资源,由容器来设置和装配。
# 构造器注入
这个就需要你的实体类必须要有有参或者无参构造。
# 无参构造方法
1. 实体类
public class User { | |
private String name; | |
public User() { | |
System.out.println("user无参构造方法"); | |
} | |
public void setName(String name) { | |
this.name = name; | |
} | |
public void show(){ | |
System.out.println("name="+ name ); | |
} | |
} |
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 | |
http://www.springframework.org/schema/beans/spring-beans.xsd"> | |
<bean id="user" class="com.Meteor.pojo.User"> | |
<property name="name" value="zed"/> | |
</bean> | |
</beans> |
3. 测试
@Test | |
public void test(){ | |
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); | |
// 在执行 getBean 的时候,user 已经创建好了,通过无参构造 | |
User user = (User) context.getBean("user"); | |
// 调用对象的方法 . | |
user.show(); | |
} |
# 有参构造方法
1. 实体类
public class User { | |
private String name; | |
public User(String name) { | |
this.name = name; | |
System.out.println("user有参构造方法"); | |
} | |
public void setName(String name) { | |
this.name = name; | |
} | |
public void show(){ | |
System.out.println("name="+ name ); | |
} | |
} |
2.beans.xml
<!-- 第一种根据 index 参数下标设置 --> | |
<bean id="user" class="com.Meteor.pojo.User"> | |
<!-- index 指构造方法,下标从 0 开始 --> | |
<constructor-arg index="0" value="zed"/> | |
</bean> |
<!-- 第二种根据参数名字设置 --> | |
<bean id="user" class="com.Meteor.pojo.User"> | |
<!-- name 指参数名 --> | |
<constructor-arg name="name" value="Aki"/> | |
</bean> |
然后感觉下面这个就很捞了
<!-- 第三种根据参数类型设置 --> | |
<bean id="user" class="com.Meteor.pojo.User"> | |
<constructor-arg type="java.lang.String" value="55open"/> | |
</bean> |
3. 测试
@Test | |
public void test(){ | |
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); | |
User user = (User) context.getBean("user"); | |
user.show(); | |
} |
然后我们可以知道,实质上加载配置文件的时候,已经初始化了对象。看无参构造的控制台输出可以推测,看有参构造就可以直接看出了。
# set 注入
要求被注入的属性,必须有 set 方法,set 方法的方法名由 set + 属性首字母大写 。实际上就是 idea 快捷键为你准备好的标准方法名字。
:::warning
如果你的对象类中同时有 set 方法和构造器方法,那么它会优先考虑构造器,因为 set 注入的本质就是调用默认的无参构造然后再 set 方法 set 参数。
:::
下图为同时使用了写了 set 方法和构造器方法导致的无法正常的使用 set 方法中常量注入。
所以这里一定要注意
:::info
以下是为了体验各种数据类型而设计的实体类
:::
public class Person { | |
private String name; | |
private Work work; | |
private String[] hobbies; | |
private List<String> books; | |
private Map<String,String> certificates; | |
private Set<String> collections; | |
private String face; | |
private Properties information; | |
// 为了避免代码块太长省略了 set 方法部分。 | |
// 注意这里是没有构造器方法的 | |
} |
public class Work { | |
private int money; | |
private String name; | |
} |
# 1. 常量注入
<bean id="person" class="com.Meteor.pojo.Person"> | |
<property name="name" value="韩金轮"/> | |
</bean> |
# 2.Bean 注入
<bean id="work" class="com.Meteor.pojo.Work"> | |
<property name="name" value="cook"/> | |
<property name="money" value="100000"/> | |
</bean> | |
<bean id="person" class="com.Meteor.pojo.Person"> | |
<property name="name" value="韩金轮"/> | |
</bean> |
# 3. 数组注入
<bean id="person" class="com.Meteor.pojo.Person"> | |
<property name="name" value="韩金轮"/> | |
<property name="work" ref="work"/> | |
<property name="hobbies"> | |
<array> | |
<value>肉蛋葱鸡</value> | |
<value>盛酱喜鲤</value> | |
<value>巨笼粧鸡</value> | |
</array> | |
</property> | |
</bean> |
# 4.List 注入
<property name="books"> | |
<list> | |
<value>青春修炼手册</value> | |
<value>如何学好小学数学</value> | |
<value>厨司的自我修养</value> | |
</list> | |
</property> | |
<!-- 为了避免越来越长,后面就只写 property 了 --> |
# 5.Map 注入
<property name="certificates"> | |
<map> | |
<entry key="金牌讲师" value="很强"/> | |
<entry key="金牌厨师" value="还就那个更强了"/> | |
</map> | |
</property> |
# 6. Set 注入
<property name="collections"> | |
<set> | |
<value>皮燕子</value> | |
<value>红皮鸭子</value> | |
</set> | |
</property> |
# 7.Null 注入
<property name="face"> | |
<null/> | |
</property> |
# 8.Properties 注入
<property name="information"> | |
<props> | |
<prop key="age">33</prop> | |
<prop key="sex">男</prop> | |
</props> | |
</property> |
# p 命名和 c 命名注入
实质上就是说清楚到底是什么注入方式,不然会发生刚才所说 set 与构造器冲突的错误。
# p 命名注入
p 命名空间注入:需要在头文件中加入约束文件
xmlns:p="http://www.springframework.org/schema/p" | |
<!--P (属性: properties) 命名空间,属性依然要设置 set 方法 --> | |
<bean id="user" class="com.Meteor.pojo.User" p:name="faker" p:age="18"/> |
# c 命名注入
c 命名空间注入:同样需要在头文件中加入约束文件
导入约束 : xmlns:c="http://www.springframework.org/schema/c" | |
<!--C (构造: Constructor) 命名空间,属性依然要设置 set 方法 --> | |
<bean id="user" class="com.Meteor.pojo.User" c:name="Rin" c:age="18"/> |
# Bean 的作用域
# singleton
bean 的默认作用域,在 Spring IoC 容器中只存在一个 Bean 实例,Bean 以单例方式存在。
<bean id="ServiceImpl" class="com.Meteor.service.ServiceImpl" scope="singleton"> |
# prototype
每次从容器中调用 bean 的时候,都返回一个新的实例,即为每次调用 getBean 的时候,相当于都执行了一次 new XXX ()
<bean id="ServiceImpl" class="com.Meteor.service.ServiceImpl" scope="prototype"> | |
<!--or--> | |
<bean id="ServiceImpl" class="com.Meteor.service.ServiceImpl" singleton="false"> |
# request
每次 HTTP 请求都会创建一个新的 Bean,该作用域只适用于 WebApplicationContext 环境。
# session
同一个 HTTP Session 贡献一个 Bean,不同的 Session 使用不同 Bean,仅适用于 WebApplicationContext 环境。
# globalSession
一般用于 Portlet 应用环境,仅适用于 WebApplicationContext 环境。