applicationContext.xml配置的所有bean都会在容器被创建的时候被创建出来,如果配置的bean较多,那么在创建容器的 时候,会产生内存过大的问题(这种情况下机器硬件性能较为落后的时候体现的比较名明显);为了解决这种问题就出现了延迟加载
需要注意的地方:Spring容器帮我们创建的User是通过空参构造器创建的,假如我们的User类中只含有含参构造器而不含有无参构造器,那么我们在创建容器(也就是执行 ApplicationContext ac=new ClassPathXmlApplicationContext(“applicationContext.xml”);的时候)会报错,因为我们的Spring容器没办法找到无参构造器并初始化一个User对象
@Test
public void Test3() {
ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
User u1=ac.getBean(User.class);
User u2=ac.getBean(User.class);
System.out.println(u1==u2);
}
输出结果为 true 说明我们创建的两个引用u1 u2指向了同一个对象,这说明了Spring容器只为我们创建了一个User对象
一般情况下使用的singleton
//initMethod
public void initMethod() {
System.out.println("userInit");
}
//destroyMethod
public void destroyMethod() {
System.out.println("destroyMethod");
}
@Test
public void Test3() {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
User user=ac.getBean(User.class);
ac.close();
}
因为将容器关闭不是ApplicationContext的方法,所以这里我们创建ClassPathXmlApplicationContext对象的时候并不需要向上转型
由实验结果可以发现,(假设是延迟加载)我们从容器中获取User对象的时候,因为延迟加载,我们请求获取User对象的时候容器才会创建,这个时候先调用User对象的无参构造器,然后执行initMethod,当我们执行ac.close();之后才会调用destroyMethod(当使用 init-method 和 destroy-method 的时候,使用 prototype 时 Spring 不会负责销毁容器对象,即 Spring 不会调用 destroy-method 所指定的方法,所以需要去掉 scope 属性,使用默认的 singleton)
普通类型和引用类型的注入
<bean name="user" class="com.chengyang.bean.User">
<property name="u_id" value="1"/>
<property name="u_username" value="崔傻屌"/>
<property name="u_password" value="123"/>
<property name="u_pet" ref="dog"/>
bean>
<bean name="dog" class="com.chengyang.bean.Pet">
<property name="petType" value="哈士奇">property>
<property name="color" value="纯白">property>
bean>
public User(String u_username, Pet u_pet) {
System.out.println("method 1:String ,Pet");
this.u_username = u_username;
this.u_pet = u_pet;
}
<bean name="dog" class="com.chengyang.bean.Pet">
<property name="petType" value="哈士奇">property>
<property name="color" value="纯白">property>
bean>
<bean name="user" class="com.chengyang.bean.User">
<constructor-arg name="u_username" value="崔仓豪"/>
<constructor-arg name="u_pet" ref="dog"/>
bean>
引用类型使用ref 否则使用value 这里配置参数顺序可以改变
@Test
public void Test4() {
ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext_injection.xml");
User user=(User) ac.getBean("user");
System.out.println(user);
}
<bean name="collection" class="com.chengyang.bean.MyCollection">
<property name="array">
<array>
<value>123value>
<value>abcvalue>
array>
property>
<property name="list">
<list>
<value>123value>
<value>abcvalue>
list>
property>
<property name="set">
<set>
<value>123212value>
<value>absacvalue>
set>
property>
<property name="map">
<map>
<entry key="username" value="root"/>
<entry key="password" value="123"/>
map>
property>
<property name="properties">
<props>
<prop key="username">崔傻屌prop>
props>
property>
bean>
package com.chengyang.bean;
import java.util.*;
public class MyCollection {
//数组
private Object[] array;
//list
private List list;
//set
private Set set;
//map
private Map map;
//properties
private Properties properties;
public Object[] getArray() {
return array;
}
public void setArray(Object[] array) {
this.array = array;
}
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public Set getSet() {
return set;
}
public void setSet(Set set) {
this.set = set;
}
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public String toString() {
return "MyCollection [properties=" + properties + "]";
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd ">
<context:component-scan base-package="com.chengyang.bean">context:component-scan>
<bean name="cat" class="com.chengyang.bean.Pet">
<property name="petType" value="橘猫">property>
<property name="color" value="橘色">property>
bean>
<bean name="dog" class="com.chengyang.bean.Pet">
<property name="petType" value="哈士奇">property>
<property name="color" value="纯白">property>
bean>
beans>
接下来就是在对象中使用注解配置
package com.chengyang.bean;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
//
//用下面的注解机代替
@Component("user")
@Scope(scopeName="singleton")
public class User2 {
//方式一:使用暴力反射注入,直接在属性前面配置
@Value(value="1")
private Integer u_id;
@Value(value="崔傻屌")
private String u_username;
private String u_password;
//add pet
private Pet u_pet;
public Pet getU_pet() {
return u_pet;
}
//自动装配
@Resource(name="dog")
public void setU_pet(Pet u_pet) {
this.u_pet = u_pet;
}
public Integer getU_id() {
return u_id;
}
public User2() {
System.out.println("User Parameterless constructor");
}
public void setU_id(Integer u_id) {
this.u_id = u_id;
}
public String getU_username() {
return u_username;
}
public void setU_username(String u_username) {
this.u_username = u_username;
}
public String getU_password() {
return u_password;
}
//方式二:在set方法上注入
@Value(value="h15839320145")//推荐在SET方法上注入
public void setU_password(String u_password) {
this.u_password = u_password;
}
@PostConstruct
public void initMethod() {
System.out.println("initMethod");
}
@PreDestroy
public void destroyMethod() {
System.out.println("destroyMethod");
}
@Override
public String toString() {
return "User2 [u_id=" + u_id + ", u_username=" + u_username + ", u_password=" + u_password + ", u_pet=" + u_pet
+ "]";
}
}
- 上面介绍了反射注入和Set前注入
- @PostConstruct 注解init 方法
- @PreDestroy注解destroy 方法
- 当配置对象是引用类型的时候使用自动装配 @Resource(name=“dog”),这个dog 是在applicationContext_annotation.xml中配置好的
- @Scope(scopeName=“singleton”)设置为单例
- @Component(“user”)代替 “<” bean name=“user” class=“com.chengyang.bean.User” “>”
@Test
public void Test1() {
ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext_annotation.xml");
User2 u2=(User2)ac.getBean("user");
System.out.println(u2);
ac.close();
}
本博客为学习笔记,素材源自网络 SIKI学院
侵删