概念:
1.依赖注入(Dependency Injection,简称DI)
2.依赖:指Bean独享的创建依赖于spring的容器。
3.注入:指Bean对象所依赖的资源,由Spring容器来设置和装配。
4.注入分为构造器注入和set方法注入,其中set方法为常用
4.1:构造注入就是需要由构造器,通过配置bean的方式使用,其中使用最多的是根据名称注入。
<!-- 根据索引给构造赋值-->
<bean id="helloSpring" class="com.spring.hellowspring.HelloEntity">
<constructor-arg index="0" value=":Spring"/>
</bean>
<!-- 根据name给构造赋值-->
<bean id="helloSpring" class="com.spring.hellowspring.HelloEntity">
<constructor-arg name="describe" value=":Spring"/>
</bean>
<!-- 通过类型给构造赋值-->
<bean name="hello,aaa,bbb" class="com.spring.hellowspring.HelloEntity">
<constructor-arg type="java.lang.String" value=":Spring"/>
</bean>
4.2通过set方法注入,要求被注入的属性必须要有set方法,set方法的名字由set+属性仔面大写,如果是boolean类型没有set方法,则用is
书写一个用户对象,并 用spring的DI注入:
@Data
@ToString
public class UserEntity {
private String name;
private UserAddress userAddress;
private String[] books;
private List<String> hobbies;
private Map<String,String> card;
private Set<String> games;
private String wife;
private Boolean married;
private Properties info;
}
xml
<!--注入地址-->
<bean id="userAddress" class="com.spring.di.UserAddress">
<property name="address" value="北京市海淀区"/>
</bean>
<!--注入用户的对象-->
<bean id="userEntity" class="com.spring.di.UserEntity">
<!--注入字符串-->
<property name="name" value="张三" />
<!--引用Bean注入-->
<property name="userAddress" ref="userAddress"/>
<!--注入set-->
<property name="books">
<array>
<value>西游记</value>
<value>红楼梦</value>
<value>三国演义</value>
<value>水浒传</value>
</array>
</property>
<!--注入List-->
<property name="hobbies">
<list>
<value>听歌</value>
<value>看电影</value>
<value>打游戏</value>
</list>
</property>
<!--注入Map-->
<property name="card">
<map>
<entry key="身份证" value="123456789"/>
<entry key="手机号" value="17656789082"/>
</map>
</property>
<!--注入Set-->
<property name="games">
<set>
<value>王者荣耀</value>
<value>吃鸡</value>
</set>
</property>
<!--注入Null值-->
<property name="wife">
<null/>
</property>
<!--注入布尔值-->
<property name="married" value="true"/>
<!--注入Properties-->
<property name="info">
<props>
<prop key="身高">190</prop>
<prop key="体重">90</prop>
</props>
</property>
</bean>
执行结果
需要注意的是这里其实调用的都是他们的set方法
另外xml名称方式还有两个p(property)命名和c(constructor-arg)命名
比如:
p是set注入,c是构造注入。使用他们两个是需要加入命名空间的
拓展:用注解的方法配置:
//开启配置
@Configuration
//设置扫描路径
@ComponentScan(basePackages = "com.spring.di")
public class ConfigurationBeans {
@Bean
public UserAddress userAddress() {
UserAddress userAddress = new UserAddress();
userAddress.setAddress("北京");
return userAddress;
}
@Bean("userEntity")
public UserEntity user() {
UserEntity user = new UserEntity();
user.setName("张三");
user.setUserAddress(userAddress());
user.setBooks(new String[]{"三国演义", "红楼梦"});
user.setHobbies(Arrays.asList("篮球", "足球"));
user.setCard(Map.of("身份证", "123456789", "军官证", "987654321"));
user.setWife(null);
user.setMarried(false);
user.setGames(Set.of("LOL", "CF"));
Properties age = new Properties();
age.setProperty("张三", "20");
user.setInfo(age);
return user;
}
}
打印结果:
Bean的作用域
在spring中,那些组成应用程序的主体及由spring ioc 容器所创建管理的对象,被称之为bean简单的说bean就是由ioc容器初始化装备及管理的对象。
几种作用域中,request和session作用域仅在web的应用中使用,(不必关心你所采用的是什么web应用框架)只能用在基于web的spring ApplicationContext环境
singleton
当一个bean的作用域为singleton时,那么spring ioc容器中指挥存在一个共享的bean实例,也就是单例模式也就是spring默认的模式。对所有bean的请求,只要id与该bean定义匹配,就会返回bean的同一个实例。就是在创建容器的时候就自动创建了一个bean对象,不管你是否使用,他都会存在,每次获取也都会获取这一个对象
<bean id="address" class="com.spring.di.UserAddress" c:address="北京市海淀区" scope="singleton"/>
测试:
@Test
public void test03(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
User user2 = (User) context.getBean("user");
System.out.println(user==user2);
}
打印为true
prototype
当一个bean的作用域为prototype时,表示时一个多例bean对象。prototype作用域的bean会导致在每个对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)时都会常见一个新的bean实例,prototype的原始类型,他在我们创建容器的时候并没有初始化,而是当我们获取这个bean的时候才会去创建一个对象,而且我们每次获取的对象都不是同一个对象。对有状态的bean应该使用prototye作用域,而对无状态的bean则应该使用singleion的作用域,
<bean id="account" class="com.foo.DefaultAccount" scope="prototype"/>
或者
<bean id="account" class="com.foo.DefaultAccount" singleton="false"/>
request
当一个bean的作用域时request时,表示在一次http请求中,一个bean定义对应一个实例,即每次请求都会创建一个新的实例。他们依据某个bean定义创建而成,该作用域仅在基于web的spting applicationcontext情境下有效,
<bean id="loginAction" class=cn.csdn.LoginAction" scope="request"/>
针对每次HTTP请求,Spring容器会根据loginAction bean的定义创建一个全新的LoginAction bean实例,且该loginAction bean实例仅在当前HTTP request内有效,因此可以根据需要放心的更改所建实例的内部状态,而其他请求中根据loginAction bean定义创建的实例,将不会看到这些特定于某个请求的状态变化。当处理请求结束,request作用域的bean实例将被销毁。
session
当一个bean的作用域为session时,表示在一个Http session中一个bean对应一个实例,该作用域仅在于web的spring applicationcontext情境下有效,
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
针对某个HTTP Session,Spring容器会根据userPreferences bean定义创建一个全新的userPreferences bean实例,且该userPreferences bean仅在当前HTTP Session内有效。与request作用域一样,可以根据需要放心的更改所创建实例的内部状态,而别的HTTP Session中根据userPreferences创建的实例,将不会看到这些特定于某个HTTP Session的状态变化。当HTTP Session最终被废弃的时候,在该HTTP Session作用域内的bean也会被废弃掉。