Spring Bean的装配有三种方式:

1、xml装配

2、java代码装配

3、自动装配(使用注解)

Spring的依赖注入方式也有三种:

1、构造器注入

2、set方法注入

3、属性输入(直接通过字段注入)

一、通过xml装配

首先准备两个java文件以供测试,分别为Student、Class,Student有name,age和班级属性以及对应的set方法,Class类则只有一个学生集合以及对应的set方法,代码如下:

package com.llg.bean;public class Student {private String name;private int age;private Class c;public Student() {}public Student(String name, int age, Class c) {this.name = name;this.age = age;this.c = c;}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}public void setC(Class c) {this.c = c;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", c=" + c +'}';}
}
package com.llg.bean;import java.util.List;public class Class {private List<Student> students;public Class() {}public Class(List<Student> students) {this.students = students;}public void setStudents(List<Student> students) {this.students = students;}@Overridepublic String toString() {return "Class{" +"students=" + students +'}';}
}

在类创建ApplicationContext.xml文件(文件名随意),并声明最基本的beans名称空间和引入对应的模式文档,如下:

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"></beans>

然后就可一在xml中通过bean元素装配bean,下面的演示代码装配了一个Student和一个Class:

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--装配student--><bean class="com.llg.bean.Student"></bean><!--装配class--><bean class="com.llg.bean.Class"></bean>
</beans>

接下来测试配置是否生效,

package com.llg.com.llg.test;import com.llg.bean.Class;
import com.llg.bean.Student;
import com.llg.config.BeanConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:ApplicationContext.xml")
public class MyTest {@Autowiredprivate Student student;@Autowiredprivate Class c;@Testpublic void test(){System.out.println(student);System.out.println(c);}
}

控制台输出:

student和class都不为空,则我们的配置是生效的,只是属性都是null,因为我们还没有为他配置,我们可以使用构造器注入和set方法来注入依赖(一开始我们说过有三种属性注入的方法,这里只有两种是因为属性注入只适用于自动装配方式(也叫注解方式)

1、构造器注入

使用<bean></bean>元素的<constructor-arg></constructor-arg>元素,constructor-arg元素主要有index(在构造器参数列表中的索引)、name(参数名称)、value(注入字面量值)、ref(注入引用)属性、type(参数类型),这样我们就可以通过如下代码来注入依赖

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--装配student--><bean class="com.llg.bean.Student"><constructor-arg index="0" name="name" type="java.lang.String" value="zhangsan"></constructor-arg><constructor-arg index="1" name="age" type="int" value="18"></constructor-arg><constructor-arg index="2" name="c" type="com.llg.bean.Class" ref="c"></constructor-arg></bean><!--装配class--><bean name="c" class="com.llg.bean.Class"></bean>
</beans>

使用构造器注入必须提供带参的构造器,index、name、type三个属性只是为了定位在构造器参数列表的位置,如果是按照构造器的顺序来注入的话,这三个属性都可以省略,字面量用value属性直接赋值,引用属性使用ref来指向已经在spring容器中配置的bean,因为student中有一个class属性,所以我在下边配置了一个class并取名为c,然后在student的配置中就可以通过c来引用这个class,测试结果如下:

package com.llg.com.llg.test;import com.llg.bean.Class;
import com.llg.bean.Student;
import com.llg.config.BeanConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:ApplicationContext.xml")
public class MyTest {@Autowiredprivate Student student;@Testpublic void test(){System.out.println(student);}
}

输出:

可以看到我们设置的值都已经生效了,上面已经讲了基本类型属性和引用属性如何配置,下面讲一下集合类型的属性如何配置,

spring分别提供了针对不同集合类型的元素分别是:

List --> <list></list>元素

Map --> <map></map>元素

数组 --> <array></array>元素

Properties --><props></props>元素

下面简单演示一下他们的用法

List:

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--准备集合元素--><bean name="s1" class="com.llg.bean.Student"></bean><bean name="s2" class="com.llg.bean.Student"></bean><bean name="s3" class="com.llg.bean.Student"></bean><!--装配class--><bean name="c" class="com.llg.bean.Class"><constructor-arg><list><ref bean="s1"></ref><ref bean="s2"></ref><ref bean="s3"></ref><!--如果是基本数据类型则使用如下方式--><!--<value>xxxx</value>--><!--<value>xxxxxx</value>--></list></constructor-arg></bean>
</beans>
package com.llg.com.llg.test;import com.llg.bean.Class;
import com.llg.bean.Student;
import com.llg.config.BeanConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:ApplicationContext.xml")
public class MyTest {@Autowiredprivate Class c;@Testpublic void test(){System.out.println(c);}
}

控制台输出:

list元素提供了ref和value子元素,分别用来配置引用数据类型和基本数据类型的属性

set:和list用法基本相同,只是如果出现相同的元素将会被过滤掉

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--准备集合元素--><bean name="s1" class="com.llg.bean.Student"></bean><bean name="s2" class="com.llg.bean.Student"></bean><bean name="s3" class="com.llg.bean.Student"></bean><!--装配class--><bean name="c" class="com.llg.bean.Class"><constructor-arg><set><!-- 引用数据类型--><ref bean="s1"></ref><!--有相同的将会被忽略--><ref bean="s1"></ref><ref bean="s2"></ref><ref bean="s3"></ref><!--基本数据类型--><!--<value>zhagnsan</value>--><!--<value>lisi</value>--><!--相同将被忽略--><!--<value>lisi</value>--></set></constructor-arg></bean>
</beans>

map:map元素中提供了entry子元素来代表结合中的一个元素,entry有四个属性,分别是key,value,key-ref,value-ref,因为在map中是以键值对存在的,而且键和值都可以是基本数据类型也可以是引用类型,所以提供了这四个属性,从他们的名字就可以看出他们的用途,如果键是基本数据类型就使用key,应用类型就使用key-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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--准备集合元素--><bean name="s1" class="com.llg.bean.Student"></bean><bean name="s2" class="com.llg.bean.Student"></bean><bean name="s3" class="com.llg.bean.Student"></bean><!--装配class--><bean name="c" class="com.llg.bean.Class"><constructor-arg><map><entry key="stuent1" value-ref="s1" ></entry><entry key="stuent2" value-ref="s2" ></entry><entry key="stuent3" value-ref="s3" ></entry></map></constructor-arg></bean>
</beans>

Properties :

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--装配class--><bean name="c" class="com.llg.bean.Class"><constructor-arg><props><prop key="studnet1" >zhangsan</prop><prop key="studnet2" >lisi</prop><prop key="studnet3" >wnagwu</prop></props></constructor-arg></bean>
</beans>

在props元素中定义prop子元素带代表Properties中的一个元素,因为Properties主要是用来读取并保存配置文件信息,所以他只来保存字符串数据,所以不想map一样有很多属性,他只有key属性,值直接卸载标签内

构造器注入的另一种方式:使用c名称空间

要使用这种方式先要在配置文件中声明c名称空间,如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:c="http://www.springframework.org/schema/c"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"></beans>

在第三行声明了c名称空间:便可以使用如下方式配置bean

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:c="http://www.springframework.org/schema/c"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--方式1--><bean class="com.llg.bean.Student" c:_0="zhangsan" c:_1="18" c:_2-ref="clas"></bean><!--方式2-->
<!--    <bean class="com.llg.bean.Student" c:name="lisi" c:age="20" c:c-ref="clas"></bean>--><bean name="clas" class="com.llg.bean.Class"></bean>
</beans>

下面解释一下属性各个组成部分的含义:“c:”表示c名称空间前缀,“_x”表示在构造器参数列表中的索引(因为xml不能以数字开头,所以在前面加下划线),“-ref”表示值是引用类型,没有则表示基本数据类型,第二中方式中名称空间前缀后面跟参数名,用c名称空间相比使用<constructor-arg>元素的唯一不足之处在于c名称空间无法注入集合类型的依赖,但我本人更喜欢使用c名称空间的方式来通过构造器注入,且喜欢方式1.因为这样看起来更加简洁。

到这里构造器注入方式就讲完了,下面介绍set方法注入。

2、set方法注入

使用构造器注入需要提供带参构造器,同理,使用set方法注入就需要提供set方法。

构造器注入使用<constructor-arg>元素

而使用set方法注入使用<property>元素

<property>元素有三个属性,

name:属性名称,通过属性名称就能找到对应的set方法从而实现set注入

value:字面量值,如果属性是基本数据类型,则使用该属性直接赋值

ref:引用,如果属性是引用类型,则使用改属性指向一个已经在Spring容器中配置好的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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean class="com.llg.bean.Student"><property name="name" value="zhagnsan"></property><property name="age" value="18"></property><property name="c" ref="clas"></property></bean><bean name="clas" class="com.llg.bean.Class"></bean>
</beans>

set方法注入集合依赖与构造器注入相同,所以就只举一个list的栗子:

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--准备集合元素--><bean name="s1" class="com.llg.bean.Student"> </bean><bean name="s2" class="com.llg.bean.Student"> </bean><bean name="s3" class="com.llg.bean.Student"> </bean><bean name="clas" class="com.llg.bean.Class"><property name="students"><list><ref bean="s1"></ref><ref bean="s2"></ref><ref bean="s3"></ref></list></property></bean>
</beans>

使用set方法注入依赖还有一种方式:使用p名称空间(与构造器注入的c名称空间相似)

看栗子

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:p="http://www.springframework.org/schema/p"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean class="com.llg.bean.Student" p:age="18" p:name="lisi" p:c-ref="c"></bean><bean name="c" class="com.llg.bean.Class"></bean>
</beans>

p名称空间前缀后面跟属性名,如果是引用类型还需要加上“-ref”,注意:需要引入p名称空间,第三行

到这里终于打xml装配bean的方式讲完了,下面继续将使用java代码装配,

二、java代码装配

用java代码装配首先要写一个配置类,并用spring的@Configuration注解标记,告诉spring这是一个配置类:栗子:

package com.llg.config;import org.springframework.context.annotation.Configuration;@Configuration
public class BeanConfig {}

现在我们就创建了一个配置类

如何装配bean:

在我们刚刚创建的配置类中写一个方法,并用@Bean注解标记,方法返回值类型为你需要放入spring容器中的bean类型,

栗子:我现在想让spring容器帮我创建一个student对象,那我可以这样来写我的java代码

package com.llg.config;import com.llg.bean.Student;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class BeanConfig {@Beanpublic Student student(){//这里可以写你想做的任何事情,只要你最后返回一个student对象即可return  new Student();}
}

那现在我们来测试一下:

package com.llg.com.llg.test;import com.llg.bean.Class;
import com.llg.bean.Student;
import com.llg.config.BeanConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration("classpath:ApplicationContext.xml")
//这里我使用的是java代码来配置,所以此处需要修改classess属性为配置类的class类型
@ContextConfiguration(classes = BeanConfig.class)
public class MyTest {@Autowiredprivate Student s;@Testpublic void test(){System.out.println(s);}
}

控制台输出

可以看到student不为空,则表示spring成功帮我们创建了student对象,说明我们的配置是生效的

如何为bean注入依赖

1、通过构造器注入

看栗子:

package com.llg.config;import com.llg.bean.Class;
import com.llg.bean.Student;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class BeanConfig {@Beanpublic Student student(){//这里可以写你想做的任何事情,只要你最后返回一个student对象即可return  new Student("zhangsan",20,cls());}@Beanpublic Class cls(){return new Class();}
}

我在创建student对象时指定了参数,那么spring就会根据我传入的参数注入依赖。

这里有一点需要注意的是在创建student对象时调用了创建班级(class)对象的cls(),那么如果我在spring容器中使用相同的代码注册多个student对象,他们的class依赖是指向同一个对象吗?代码如下:

package com.llg.config;import com.llg.bean.Class;
import com.llg.bean.Student;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class BeanConfig {@Beanpublic Student student1(){return  new Student("zhangsan",20,cls());}@Beanpublic Student student2(){return  new Student("lisi",18,cls());}@Beanpublic Student student3(){return  new Student("wangwu",22,cls());}@Beanpublic Class cls(){return new Class();}
}

如代码所示,我在spring容器中注册了三个student对象,他们的name和age属性都不同,但他们的class属性都是调用cls()方法来的,按照我们平时积累的经验来看,他们肯定是不想等的,因为每调用一次cls()方法,都相当于重新new了一个对象返回,但是事实并非如此,这是因为spring会拦截使用了@Bean注解的方法,并直接返回最初创建的那个对象,而并不是每次都进行实际的调用,感兴趣的可以自己测试。

如果没有理解上面所说的也不要紧,spring提供了另一种构造器注入的方式

看栗子:

package com.llg.config;import com.llg.bean.Class;
import com.llg.bean.Student;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class BeanConfig {@Beanpublic Student student1(Class c){return  new Student("zhangsan",20,c);}@Beanpublic Class cls(){return new Class();}
}

这里和刚才的方式的区别在于定义了一个Class(班级)类型的参数c,在创建student不再调用cls()方法,而是直接使用参数c,

spring会在调用这个方法前去容器中找Class类型的bean并赋值给c.这种方式容易理解。

2、使用set方法注入

看栗子:

package com.llg.config;import com.llg.bean.Class;
import com.llg.bean.Student;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class BeanConfig {@Beanpublic Student student1(Class c){Student student = new Student();student.setName("张三");student.setAge(25);student.setC(c);return  student;}@Beanpublic Class cls(){return new Class();}
}

使用set方法注入同样是给方法生命一个参数,但是在方法里面是调用了set方法而不是带参构造器。

三、自动装配(使用注解扫描)

spring的注解扫描默认是关闭的,所以需要设置开启扫描

以xml配置开启扫描:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="com.llg"></context:component-scan>
</beans>

使用xml开启扫描,需要引入context名称空间以及模式文档

并使用<context:component-scan>开启扫描

base-package设置需要扫描的包以及子包,如果不设置,则扫描本包及其子包

使用java代码开启扫描,代码如下:

package com.llg.config;import com.llg.bean.Class;
import com.llg.bean.Student;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;@Configuration
@ComponentScan(basePackages = "com.llg")
public class BeanConfig {}

创建一个配置类,然后使用@Configuration和@ComponentScan注解标记,basePackages属性的作用与xml中的base-packag属性相同。

开启扫描之后,spring就会扫描指定包下的所有类,扫描到有@Component注解标记的类就会将他注册到spring容器中

就像这样:

package com.llg.bean;import org.springframework.stereotype.Component;@Component
public class Student {}

测试一下

package com.llg.com.llg.test;import com.llg.bean.Class;
import com.llg.bean.Student;
import com.llg.config.BeanConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration("classpath:ApplicationContext.xml")
//这里我使用的是java代码来配置,所以此处需要修改classess属性为配置类的class类型
@ContextConfiguration(classes = BeanConfig.class)
public class MyTest {@Autowiredprivate Student s;@Testpublic void test(){System.out.println(s);}
}

控制台输出

student不为null说明配置生效

将bean注册到容器之后,如何注入他的依赖呢?

答案是使用@Autowired注解

看代码:

package com.llg.bean;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class Student {private String name;private int age;//如果@Autowired标记在属性上,则代表使用属性注入(直接通过字段注入)@Autowiredprivate Class c;public Student() {}//如果@Autowired标记在带参构造器上,则代表使用构造器注入
//    @Autowiredpublic Student(Class c) {this.c = c;}//如果@Autowired标记在属性的set方法上,则代表使用set方法注入
//    @Autowiredpublic void setC(Class c) {this.c = c;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", c=" + c +'}';}
}
通过将@Autowired注解写在不同的位置来表明使用不同的注入方法

到这里就将spring的装配方式介绍完了,本人比较喜欢使用自动装配的方式,但是自动装配有一点每种不足的是如果我想想spring容器中注入第三方包中的类,那自动装配就无能为力了,因为我们不能去修改第三方包的内容(为他加上@Component注解),还好spring的三种装配方式不是互斥的,所以在我们的项目中可以三种方法搭配使用。

自动装配与xml或者与java代码配置搭配不需要额外的配置

xml配置java代码配置的搭配则需要在其中一种配置中引入另一种配置

假设这样一种场景,我配置bean都是在xml中配置,但有一天由于业务需求,xml中配置无法满足我们的需求,那么我们不得不使用其他的配置,比如使用java代码,那我现在将student和class的装配分别放在xml和java代码中,如下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:p="http://www.springframework.org/schema/p"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean class="com.llg.bean.Student" p:name="lisi" p:age="12" p:c-ref="c"></bean>
</beans>
package com.llg.config;import com.llg.bean.Class;
import com.llg.bean.Student;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;@Configuration
@ComponentScan(basePackages = "com.llg")
public class BeanConfig {@Bean(name = "c")public Class cls(){return new Class();}
}

我现在还没有做任何是他们联系起来的操作,如果直接运行下面的测试代码:

package com.llg.com.llg.test;import com.llg.bean.Class;
import com.llg.bean.Student;
import com.llg.config.BeanConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:ApplicationContext.xml")
//@ContextConfiguration(classes = BeanConfig.class)
public class MyTest {@Autowiredprivate Student s;@Testpublic void test(){System.out.println(s);}
}

报错如下:找不到名为c这个bean

这是因为只加载了xml配置文件(测试代码13行),并没有加载我们的配置类,所有spring容器中没有名为c的bean,而我配置student时又引用了一个名为“c"的bean,所以报错。

如何在xml中引入java配置类:直接使用<bean>元素,如图

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:p="http://www.springframework.org/schema/p"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean class="com.llg.config.BeanConfig"></bean><bean class="com.llg.bean.Student" p:name="lisi" p:age="12" p:c-ref="c"></bean></beans>

这样就解决了刚才的问题,再次运行

xml文件里还可以引入其他xml文件(如果要装配的bean很多,写在一个文件中可能会难以阅读和维护,所以可以拆分成多个xml文件,然后用一个主配置文件引入他们)。

可以在xml中使用<inport>标记引入其他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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><import resource="class.xml"></import><import resource="student.xml"></import>
</beans>

如何在java配置类中引入xml文件

使用@ImportResource("需要引入的xml配置文件")

如:

package com.llg.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;@Configuration
@ImportResource("ApplicationContext.xml")
public class BeanConfig {}

这样就将配置文件引入了java配置类

同理,一个主配置类里也可以引入其他配置类

像下面这样,我就将StudentConfig和ClassConfig两个配置类引入了BeanConfig猪配置类中

package com.llg.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;@Configuration
@Import({StudentConfig.class,ClassConfig.class})
public class BeanConfig {}

注意:引入xml使用@ImportResource,引用java配置类使用@Import,如果要引用多个,就写成数组的形式

到这里本博客就写完了,如果有写错或者不完善的地方请多包涵,可以联系我修改,谢谢

Spring Bean装配以及依赖注入相关推荐

  1. Spring Bean 装配和依赖注入

    Spring IOC 容器的依赖注入工作可以分为两个阶段.第一个阶段可以认为是构建和收集 Bean 定义的阶段,在这个阶段中,我们可以通过 xml 或者 Java 代码的方式定义一些 Bean,然后通 ...

  2. 一步一步手绘Spring DI运行时序图(Spring 自动装配之依赖注入)

    相关内容: 架构师系列内容:架构师学习笔记(持续更新) 一步一步手绘Spring IOC运行时序图一(Spring 核心容器 IOC初始化过程) 一步一步手绘Spring IOC运行时序图二(基于XM ...

  3. Spring(二)--------Spring配置、DI依赖注入、Bean自动装配

    Spring(二)--------Spring配置.DI依赖注入.Bean自动装配 5.Spring配置 5.1 别名 设置别名:第一种方式alias <!--其中name为ID的对应值--&g ...

  4. Spring IOC容器的依赖注入流程(收集和注册、分析和组装)

    Spring IOC容器的依赖注入流程 Spring IOC容器的依赖注入工作可以分为两个阶段: 阶段一:收集和注册 第一个阶段可以认为是构建和收集bean定义的阶段,在这个阶段中,我们可以通过XML ...

  5. 回客科技 面试的 实现ioc 容器用到的技术,简述BeanFactory的实现原理,大搜车面试的 spring 怎么实现的依赖注入(DI)...

    前言:这几天的面试,感觉自己对spring 的整个掌握还是很薄弱.所以需要继续加强. 这里说明一下spring的这几个面试题,但是实际的感觉还是不对的,这种问题我认为需要真正读了spring的源码后说 ...

  6. Spring的核心机制依赖注入简介

    Spring能有效地组织J2EE应用各层的对象.不管是控制层的Action对象,还是业务层的Service对象,还是持久层的DAO对象,都可在Spring的管理下有机地协调.运行.Spring将各层的 ...

  7. 关于mysql注入说法正确的是_1. 在 Spring中,下列关于 依赖注入 的 说法 , 正确的是( ) 。_学小易找答案...

    [简答题]1基本流程练习 2时间轴嵌套 3简单应用 [简答题]请解释什么是MVC? [多选题]在 Hibernate 中,下 列 说法正确的有 [多选题]1. 关于 Spring,下列说法不正确的是( ...

  8. Spring 的控制反转/依赖注入

    第一章 Spring 的控制反转/依赖注入 回顾 增删改查. 课前测: 本章内容 spring:春天 IOC:将创建对象的权力交给 spring 核心容器去控制.工厂模式 BeanFactory: 懒 ...

  9. Spring Bean装配(上)

    Bean:在spring的IOC里面,把配置到IOC容器里面的实体或者是对象都称为Bean Bean配置项 Bean的作用域 Bean的生命周期 Bean的自动装配 Resources&Res ...

  10. Spring使用注解配置依赖注入

    大部分情况下,使用Spring配置依赖注入时,都是使用注解来进行配置,因为注解比xml要方便和简单.不过类似于数据源对象这种配置信息容易变更的对象除外,这种对象使用xml文件来进行配置会更适合,方便于 ...

最新文章

  1. 美团五大最受欢迎的开源项目!
  2. 查找文本字母并且统计个数
  3. TensorFlow:Windows下使用TensorFlow-Python版本
  4. SQL -- 多表查询
  5. 高级java必须清楚的概念:原子性、可见性、有序性
  6. ios刷android8.0,颤抖吧 iOS, Android 8.0正式发布!
  7. 将字符串中的指定字符全局替换
  8. MySQL运算符优先级顺序
  9. vs2005 创建解决方案不显示,解决方案管理器中看不到解决方案节点的解决办法...
  10. android监听器作用,android - 监听器和接收器(Android)有什么区别?
  11. 【LeetCode - 798】得分最高的最小轮调(转化法)
  12. mfc打开一个.txt文件并进行处理_文件处理方法Python
  13. myisam和innodb到底谁更快
  14. 上传docker到阿里云镜像仓库
  15. 力压腾讯!《原神》连续5个月成中国手游海外收入冠军
  16. Vue.js安装方法
  17. 蓝桥杯 字母组串(递归)
  18. 1380 D - Berserk And Fireball(思维,贪心)
  19. 中标麒麟运行java,开发知识-中标麒麟安装达梦数据库(DM8)
  20. 随机森林算法学习(RandomForest)

热门文章

  1. 钉钉发起审批流程分析
  2. 跟我一起水疗的哥俩儿,其实挺猛的!
  3. Team Queue
  4. python背单词游戏,python背单词小程序
  5. Mac搭建本地局域网SVN服务(Cornerstone)
  6. Smartbi的使用
  7. java eclipse改名_Java EE更名Jakarta EE,但Oracle还给Eclipse基金会提了很多要求 - IT之家...
  8. 外汇汇率接口 java_免费的货币汇率API
  9. mysql的填充因子_数据库的索引和填充因子fillfactor
  10. 第二天:Kafka API操作