目录
name属性:属性的名称,与Bean中setter方法的名称一致。
标签:标签内的文本指定属性的值,类型为字面值类型。可使用null值,将属性的值设置为null。
1 Bean的装配方式
什么是Bean的装配?
Bean的装配可以理解为依赖关系注入,Bean的装配方式即Bean依赖注入的方式。Spring容器支持多种形式的Bean的装配方式,如基于XML的装配、基于注解(Annotation)的装配和自动装配(其中最常用的是基于注解的装配),本次课将主要讲解这三种装配方式的使用
2 基于XML的装配
2.1 传入参数的类型
装配的本质:通过<constructor-arg>元素调用有参构造器,或<property>元素调用setter方法,调用时传入参数的类型有:
2.2 字面值注入(SpringDIConfig)
name属性:属性的名称,与Bean中setter方法的名称一致。
value属性:属性的值,指定的值是字面值。
<value>标签:标签内的文本指定属性的值,类型为字面值类型。可使用null值,将属性的值设置为null。
<bean id="students" class="cn.com.sise.pojo.Students">
<constructor-arg name="num" value="1640707000" />
<property name="name">
<value>黄霸天</value>
</property>
<constructor-arg name="major">
<value>物联网工程</value>
</constructor-arg>
</bean>
public class Student {
public Student() {
System.out.println("OK");
}
public Student(int age) {
System.out.println("age="+age);
}
public Student(String name) {
System.out.println("name="+name);
}
public Student(int age,String name) {
System.out.println("age="+age+",name="+name);
}
public Student(Date now) {
System.out.println("现在的时间是:"+now);
}
public Student(List<Object> list) {
for (Object object : list) {
System.out.println(object);
}
}
public Student(Object [] array) {
for (Object object : array) {
System.out.println(object);
}
}
public Student(Set<Object> set) {
for(Object object : set) {
System.out.println(object);
}
}
public Student(Map<String,Object> map) {
Set<String> keys = map.keySet();
for (String key : keys) {
System.out.println(key+":"+map.get(key));
}
}
public Student(Properties properties) {
System.out.println(properties.get("driver"));
System.out.println(properties.get("userName"));
System.out.println(properties.get("password"));
System.out.println(properties.get("url"));
}
}
第一种方法,按顺序排列
<bean class="Student">
<!-- 这里我们直接使用标签属性value,直接给构造函数参数列表赋值,
写了两个constructor-arg标签,则就是对应有两个参数的构造函数,
想要赋的值 按参数列表的顺序写就可以了 -->
<constructor-arg value="12"></constructor-arg>
<constructor-arg value="张三"></constructor-arg>
</bean>
第二种方法,使用name标签属性
<bean class="Student">
<!-- 这里的name标签属性对应的就是参数列表中的参数名,不按顺序写他也会自动比对的 -->
<constructor-arg name="name" value="张三"></constructor-arg>
<constructor-arg name="age" value="12"></constructor-arg>
</bean>
第三种方法,使用index标签属性
<bean class="Student">
<!-- index为参数列表中参数的顺序,从0开始 -->
<constructor-arg index="1" value="张三"></constructor-arg>
<constructor-arg index="0" value="12"></constructor-arg>
</bean>
第四种方法,使用type标签属性
<bean class="Student">
<!-- 这里int不可以是java.lang.Integer,要和参数数据类型严格一致 -->
<constructor-arg type="int" value="12"></constructor-arg>
<constructor-arg type="java.lang.String" value="张三"></constructor-arg>
</bean>
2.3 引用注入(SpringDIConfig)
2.4 引用注入举例(SpringDIConfig)
<bean id="birthDay" class="cn.com.sise.pojo.BirthDay"/>
<bean id="school" class="cn.com.sise.pojo.School">
<constructor-arg name="students" ref="students">
</constructor-arg>
<constructor-arg name="teachers">
<ref bean="teachers"></ref>
</constructor-arg>
</bean>
<property name="birth" ref="birthDay" />
<constructor-arg>标签的属性如上图:
index属性:指定参数是第几个,值从0开始
type属性:指定参数类型,决定使用哪个构造函数
<constructor-arg index="0" type="java.lang.String" value="AA" />
2.5 集合类型注入(XMLBasedAssembly)
<bean id="order" class="com.qst.chapter07.config.Order">
<property name="myList">
<list>
<value>1234</value>
<ref bean="orderItem1" />
</list>
</property>
</bean>
<set>:声明该依赖对象为一个set集合,用法与list标签相同。
set集合可包含多个内部bean,ref,collection或value元素。
<property name="myList">
<set>
<value>1234</value> <ref bean="orderItem1" />
</set>
</property>
</bean>
list标签和set标签中的属性:
value-type属性:指定值的类型,
merge="default":使用父/子bean时,启用合并集。
<map>:声明该依赖对象为一个map集合,其下<entry>:
<entry>:声明map集合下的一个键值对,其属性如下图所示,其子标签如下图:
key属性:键值对中的键,一般为字符串
<value>:键值对中的值,类型为字面值
<ref>:键值对中的值,引用其他的Bea
<property name="someMap">
<map key-type="java.lang.String" value-type=“java.util.Date">
<entry value="some1" key="key1"></entry>
<entry value-ref="some2" key="key2"></entry>
<entry value-ref="some3" key="key3"></entry>
</map>
</property>
<props>:声明该依赖对象为一个properties集合,其下:
<prop>:用于设置集合中的一个键值对
key属性:指明键值对中的键,一般为字符串
文本内容:指明键值对中的值,一般为字符串
属性元素与map元素的区别:值必须是字符串,可能为空
<bean id="order" class="com.qst.chapter07.config.Order">
<property name="myProp">
<props>
<prop key="aaa">AAA</prop>
<prop key="bbb">BBBBB</prop>
</props>
</property>
</bean>
①命名空间注入(用的不多)
对于设置注入与构造注入,在配置文件中,还可使用命名空间注入,让注入的值以<bean/>标签的属性的方式出现。
根据注入实现方式,分为P命名空间注入与C命名空间注入。
p命名空间注入:采用设值注入方式。
c命名空间注入:采用构造注入方式。
注入的Bean对象的属性类型:
基本类型:p:属性名="属性值"
引用类型:ref属性 p:属性名-ref="其他Bean的id"
2.6 复合类型注入(Spring配置依赖)
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
<!-- 使用p命名空间,通过通过set方法注入bean定义-->
<bean id="stu2" class="cn.com.sise.Student"
p:sNo="002" p:sName="Tom"
p:age="22" p:banji-ref="banji">
</bean>
<!-- 使用c命名空间,通过构造方法注入的bean定义-->
<bean id="stu3" class="cn.com.sise.Student"
c:_0=“003” c:_1=“Jerry " //c:_0表示第一个参数
c:_2="22" c:_3-ref="banji">
</bean>
c:_n=“参数值”中的n表示注入的是第几个参数(从0开始)
util命名空间:可以快速的定义list、map、set等。
首先需要在XML配置文件中引入其对应的util命名空间,见图
这部分内容,大家感兴趣的自己看看Spring| Spring之util命名空间_YvesHe的博客-CSDN博客_spring util
Spring容器不能直接获取该Bean,因此嵌套Bean不需要id
<!-- 使用嵌套Bean -->
<bean id="stu4" class="cn.com.sise.Student"
p:sNo="004" p:sName="Tom" p:age="22">
<property name="banji">
<bean class="cn.com.sise.BanJi"
p:cNo="2" p:cName="Web2"></bean>
</property>
</bean>
2.7 基于XML装配的步骤
创建Java类,提供有参、无参构造及属性setter方法;
public User(String username, Integer password, List<String> list) {
super();
this.username = username;
this.password = password;
this.list = list;
}
public User() { super();}
//省略属性setter方法
创建Spring配置文件beans5.xml,用2种方式配置Bean;
<bean id="user1" class="com.itheima.assemble.User">
<constructor-arg index="0" value="tom" />
...
</bean>
<bean id="user2" class="com.itheima.assemble.User">
<property name=“username” value=“张三” />
...
</bean>
创建测试类,测试程序。
public class XmlBeanAssembleTest {
public static void main(String[] args) {
String xmlPath = "com/itheima/assemble/beans5.xml";
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext(xmlPath);
System.out.println(applicationContext.getBean("user1"));
System.out.println(applicationContext.getBean("user2"));
}
}
3 基于注解的装配
3.1 Spring中常用的注解
@Component | 描述Spring中的Bean,它是一个泛化的概念,仅仅表示一个组件。 |
@Repository | 将数据访问层(DAO)的类标识为Bean。 |
@Service | 将业务层(Service)的类标识为Spring中的Bean。 |
@Controller | 将控制层(Controller)的类标识为Bean 。 |
@Autowired | 对Bean的属性、属性的setter方法及构造方法进行标注,配合对应的注解处理器完成Bean的自动装配,默认是byType的自动装配。 |
@Qualifier | byName的自动装配,指定注入Bean的名称,对Bean的成员变量、方法入参、构造函数入参进行标注,常与@Qualifier 结合使用。 |
@Inject | 与上两个注释用法相同,由JSR-330提供。 |
@Resource | 功能同@Autowired,有两个重要属性:name和type。分别解析为Bean实例的名称和类型 |
@Bean | 告诉方法,产生一个Bean对象,并交给Spring管理。 |
@ComponentScan | 默认会扫描该配置类所在的包下所有的配置类,相当于<context:component-scan>。 |
@PostConstruct | 修饰方法,相当于init-method属性 |
@PreDestroy | 修饰方法,相当于destroy-method属性 |
@Lazy | 指定延迟初始化。相当于lazy-init属性 |
@Value | 属性注入值(属性上) |
@Scope | 指定Bean的作用域,相当于scope属性。 |
@DependsOn | 强制初始化其他Bean,对应depends-on属性。 |
3.2 基于Annotation的装配
创建接口UserDao,并定义方法;
创建接口实现类UserDaoImpl,用@Repository声明类;
@Repository("userDao")
public class UserDaoImpl implements UserDao{
public void save(){
System.out.println("userdao...save...");
}
}
创建接口UserService,并定义方法;
创建接口实现类UserServiceImpl,用@Service声明类,并使用@Resource注入UserDao属性;
@Service("userService")
public class UserServiceImpl implements UserService{
@Resource(name="userDao")
private UserDao userDao;
public void save() {
this.userDao.save();
}
}
创建控制器类,用@Controller声明,并使用@Resource注入UserService属性;
@Controller("userController")
public class UserController {
@Resource(name="userService")
private UserService userService;
public void save(){
this.userService.save();
}
}
创建Spring配置文件,配置Bean;
<context:annotation-config />
<bean id="userDao" class="com.itheima.annotation.UserDaoImpl"/>
<bean id="userService" class="com.itheima.annotation.UserServiceImpl"/>
<bean id="userController" class="com.itheima.annotation.UserController"/>
创建测试类,测试程序。
public class AnnotationAssembleTest {
public static void main(String[] args) {
String xmlPath="com/itheima/annotation/beans6.xml";
ApplicationContext applicationContext=
new ClassPathXmlApplicationContext(xmlPath);
UserController userController= (UserController) applicationContext.getBean("userController");
userController.save();
}
}
小提示: 除了可以像示例中通过<bean>元素来配置Bean外,还可以通过包扫描的形式来配置一个包下的所有Bean:
<context:component-scan base-package="com.itheima.annotation" />
3.3 包扫描的形式(SpringScan)
上述案例除了可以通过<bean>元素来配置Bean外,还可以通过包扫描的形式来配置一个包下的所有Bean:
<context:component-scan base-package="com.itheima.annotation"/>
其使用步骤如下:
1、在xml配置文件中,引入context命名空间,并添加<context:component-scan base-package="需要扫描的包(含子包) " >标签。扫描元素时,不需要在XML中提供任何bean配置元数据。
3、标注组件:为需要被扫描的类添加相应的注解。
4、测试:测试相应的组件是否被纳入Spring容器(是否被扫描)
//如果输出不为空,则测试类已被扫描并且纳入了Spring容器
修改XML配置文件
<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.xsd">
<context:component-scan
base-package="cn.com.sise.service,cn.com.sise.action"/>
</beans>
3.4 自动装配(autowire)
将一个Bean自动的注入到到其他Bean的Property中。 Spring的<bean>中包含一个autowire属性,通过设置autowire的属性值来自动装配Bean。autowire属性有5个值,其值如下表所示:
(1)autowire="byName"
当一个<bean>带有autowire="byName"的属性时:
<bean autowire="byName" id="school" class="com.sise.School"/>
①查找Bean类中所有的set方法名(或属性名),如setStudents,获得将set去掉并且首字母小写的字符串,即student。
public class School {
private Students students;
private Teachers teachers;
public void setStudents(Students students) {
this.students = students;}
public void setTeachers(Teachers teachers) {
this.teachers = teachers;}}
<bean id="students" class="com.sise.Students"/>
<bean id="teachers" class="com.sise.Teachers"/>
(2)autowire="byType"
<bean autowire="byType" id="school" class="com.sise.School"/>
public class School {
private Students students;
private Teachers teachers;
public void setStudents(Students students) {
this.students = students;}
public void setTeachers(Teachers teachers) {
this.teachers = teachers;}}
<bean id="students" class="com.sise.Students"/>
<bean id="teachers" class="com.sise.Teachers"/>
(3)autowire="constructor"
<bean autowire="constructor" id="school" class="com.sise.School"/>
<bean id="students" class="com.sise.Students"/>
<bean id="teachers" class="com.sise.Teachers"/>
3.5 自动装配的使用步骤
自动装配,使用方式如下:
修改上一节UserServiceImple和UserController,分别增加类属性的setter方法;
修改Spring配置文件,使用autowire属性配置Bean;
重新测试程序。
<bean id="userDao" class="com.itheima.annotation.UserDaoImpl"/>
<bean id="userService" class="com.itheima.annotation.UserServiceImpl" autowire="byName"/>
<bean id="userController" class="com.itheima.annotation.UserController" autowire="byName"/>
4 本讲小结
本讲对Spring的BeanBean的三种装配方式进行了详细的讲解,首先讲解了Bean装配的概念,接下来介绍了基于XML的装配和基于注解的装配,最后以案例介绍了不同方式的Bean的装配的步骤。