Spring框架作为Bean的管理容器,其最经典最基础的Bean配置方式就是纯XML配置,这样做使得结构清晰明了,适合大型项目使用。Spring的XML配置虽然很繁琐,而且存在简洁的注解方式,但读懂XML配置文件对我们来说依然很重要,尚且对于老系统维护必不可少的面对XML配置。
下面通过案例来理解XML配置。
案例:(一个基础的Bean)
public classPet {privateString petType;privateString color ;publicString getColor() {returncolor;
}public voidsetColor(String color) {this.color =color;
}publicString getPetType() {returnpetType;
}public voidsetPetType(String petType) {this.petType =petType;
}publicString toString(){return"petType: "+petType+" color: "+color;
}
}
public classUser {
String id;
String name;
String passWord;
Pet pet;publicPet getPet() {returnpet;
}public voidsetPet(Pet pet) {this.pet =pet;
}publicUser(){
System.out.println("spring 需要一个空参构造!");
}publicString getId() {returnid;
}public voidsetId(String id) {this.id =id;
}publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}publicString getPassWord() {returnpassWord;
}public voidsetPassWord(String passWord) {this.passWord =passWord;
}
@OverridepublicString toString() {return "User{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", passWord='" + passWord + '\'' +
", pet=" + pet +
'}';
}public voidinit(){
System.out.println("User初始化执行init方法!");
}public voiduserDestroy(){
System.out.println("userDestroy方法被执行!");
}
}
importcom.bing.tao.bean.User;importorg.junit.jupiter.api.Test;importorg.springframework.context.support.ClassPathXmlApplicationContext;public classHelloSpring {/*** IOC的反转:创建对象这份工作由我们自己执行反转给spring帮我们执行;
* IOC的控制:就是由spring帮我们负责创建销毁对象,掌控对象的生命周期等,我们在需要使用对象的时候跟Spring申请即可;
* IOC是一种编程思想,也是一种新的设计模式,它需要DI(依赖注入)技术的支持;
* spring是一个容器,它将帮我们管理对象*/@Testpublic voidTest1(){//根据spring配置文件获取容器对象//ApplicationContext 配置的所有bean都会在容器创建的时候被创建出来//如果配置的bean较多,那么在创建容的时候,会产生内存过大的问题;这种情况在机器硬件性能较为落后的时候体现的比较明显;//延迟加载 true就是创建容器时不加载配置的bean对象,在获取的时候才创建;
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
User user= (User) applicationContext.getBean("user");
System.out.println("user: "+user);//通过getBean获取配置好的user对象(程序员向spring容器要对象)
user= applicationContext.getBean(User.class);
System.out.println("user: "+user);
applicationContext.close();
}
}
重要的配置:(创建一个名字叫:applicationContext.xml的配置文件)
运行结果:
配置文件,已经将标签含义说明清楚。补充一点:如果是多例则spring不在管理bean而是交给你管理,销毁方法将不再执行。
Spring XML配置如何支持构造函数和复杂数据类型(List等):
修改User类:
public classUser {
String id;
String name;
String passWord;
Pet pet;publicPet getPet() {returnpet;
}public voidsetPet(Pet pet) {this.pet =pet;
}publicUser(){
System.out.println("spring 需要一个空参构造!");
}publicUser(String name, Pet pet) {
System.out.println("打印构造方法1:name :"+name +"pet:"+pet);this.name =name;this.pet =pet;
}publicUser(Pet pet,String name) {
System.out.println("打印构造方法2:name :"+name +"pet:"+pet);this.name =name;this.pet =pet;
}publicString getId() {returnid;
}public voidsetId(String id) {this.id =id;
}publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}publicString getPassWord() {returnpassWord;
}public voidsetPassWord(String passWord) {this.passWord =passWord;
}
@OverridepublicString toString() {return "User{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", passWord='" + passWord + '\'' +
", pet=" + pet +
'}';
}public voidinit(){
System.out.println("User初始化执行init方法!");
}public voiduserDestroy(){
System.out.println("userDestroy方法被执行!");
}
}
新增测试方法:
importcom.bing.tao.bean.MyCollection;importcom.bing.tao.bean.User;importorg.junit.jupiter.api.Test;importorg.springframework.context.support.ClassPathXmlApplicationContext;public classHelloSpring2 {
@Testpublic voidTest1(){
ClassPathXmlApplicationContext applicationContext= new ClassPathXmlApplicationContext("applicationContext_Injection.xml");
User user= (User) applicationContext.getBean("user");
System.out.println(user);
System.out.println("-----------------分割线-----------------");
MyCollection myCollection= (MyCollection) applicationContext.getBean("myCollection");
System.out.println(myCollection);
}
}
新增配置文件:applicationContext_Injection.xml
配置内容如下:
123
abc
456
def
老李
25
运行结果:
看到这边,大部分人都会觉得,每一个Bean都要这么操作一下,这么复杂,还不如直接写代码呢。
接下来,我们来简化配置。
先来简化配置:(新建一个配置文件:applicationContext_annotation.xml)
将User修改成:
importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.Scope;importorg.springframework.stereotype.Component;importjavax.annotation.PostConstruct;importjavax.annotation.PreDestroy;/*** @Component 用于标记该bean需要Spring实例化。
* @Scope 标签用于标记该bean是单例还是多例,singleton表示单例,prototype多例。*/@Component("user")
@Scope(scopeName= "singleton")public classUser {/*** @Value标签可以将括号中的值注入到Spring生成的Bean中*/@Value("1")
String id;
@Value("蕾蕾")
String name;
@Value("123")
String passWord;publicString getId() {returnid;
}public voidsetId(String id) {this.id =id;
}publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}publicString getPassWord() {returnpassWord;
}public voidsetPassWord(String passWord) {this.passWord =passWord;
}publicString toString(){return"name: "+name+" id: "+id;
}//构造后调用
@PostConstructpublic voidinit(){
System.out.println("User初始化执行init方法!");
}//销毁前调用
@PreDestroypublic voiduserDestroy(){
System.out.println("userDestroy方法被执行!");
}
}
创建一个测试方法:
importcom.bing.tao.bean.User;importorg.junit.jupiter.api.Test;importorg.springframework.context.support.ClassPathXmlApplicationContext;public classHelloSpring3 {
@Testpublic voidTest1(){
ClassPathXmlApplicationContext applicationContext= new ClassPathXmlApplicationContext("applicationContext_annotation.xml");//通过getBean获取配置好的user对象(程序员向spring容器要对象)
User user= (User) applicationContext.getBean("user");
System.out.println(user);//scope="singleton" 是单例下才能出发销毁bean方法,如果是多例则spring不在关联bean而是交给你管理。
applicationContext.close();
}
}
运行结果:
这样就可以批量设置模式一样的Bean结构了。XML的配置就可以很好的简化。同时还倒逼了目录结构的整齐。