Spring系列二Bean装配
Spring Bean装配
三种方式:
1.隐式的bean发现机制和自动装配
2.在Java中进行显示的配置
3.在XML中进行显示配置
1.隐式的bean发现机制和自动装配
需要两个前提,如何隐式发现相应的bean类,如何隐式的满足bean的依赖?
解决方法:使用组件扫描,自动装配。
组件扫描:
Spring会自动发现应用上下文中所创建的bean,使用@ComponentScan注解,直接使用@ComponentScan注解的话,会默认扫描和配置类相同的包下的组件,如果想增加扫描的包,可以在注解中使用basePackages参数,来增加需要扫描的包。
配置类:
定义Spring的装配规则,使用@Configuration来告诉Spring这是一个组件
组件:
需要为其创建Bean的类,使用@Component注解,组件扫描扫描到这个注解,便为其创建bean,默认根据类名的ID来创建bean的名称,即类名的第一个字母小写,当然可以指定名称,例如:@Component("name")
自动装配
Spring根据注解,来完成Bean之间的依赖关系,使用@Autowired注解,可以用在构造器上或者Setter方法上,当进行自动装配的时候,Spring会满足自动装配,去寻找相应的bean,如果没有,则会抛异常,可以设置参数required属性为false,当Spring进行自动转配的时候,如果没有匹配到bean的时候,则会让这个bean处于未装配状态。
具体案例:
package com.dong.BeanAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Father {
private String name="刘军";
private int age = 54;
private Son son;
public Son getSon() {
return son;
}
@Autowired
public void setSon(Son son) {
this.son = son;
}
public void toSay() {
System.out.println("good");
}
}
package com.dong.BeanAnnotation;
import org.springframework.stereotype.Component;
@Component
public class Son {
private String name="刘D";
private int age=24;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.dong.BeanAnnotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Configuration:告诉容器,这个是配置类,
* ComponentScan:进行组件扫描,默认扫描与配置类相同的包,也可以使用参数basePackages来指定多个包
* Component:即该类为组件,会为这个类创建bean,默认根据类名的ID来创建bean的名称,即类名的第一个字母小写,当然可以指定名称
* Autowired:可以用在构造器上或者Setter方法上,当进行自动装配的时候,Spring会满足自动装配,去寻找相应的bean,如果没有,则会抛异常,
* 可以设置参数required属性为false,当Spring进行自动转配的时候,如果没有匹配到bean的时候,则会让这个bean处于未装配状态。
* @author liuD
*/
@Configuration
@ComponentScan("com.dong.BeanAnnotation")
public class Clinet {
public static void main(String args[]) {
ApplicationContext context = new AnnotationConfigApplicationContext(com.dong.BeanAnnotation.Clinet.class);
Father father = (Father) context.getBean("father");
father.toSay();
}
}
2.在Java中显示配置
创建配置类,使用@Configuration表明这个类是一个配置类,该类应该包含在Spring应用上下文中如何创建bean的细节,
声明bean,使用@Bean注解,并编写一个方法,这个方法创建我们需要的bean,@Bean注解会让Spring这个方法返回一个对象,该对象要成为Spring应用上下文中的bean,默认情况下,bean的名字与方法名一致,如果想要改变名字,则可以使用name属性指定一个不同的名字,@Bean(name="newname")
依赖注入,引用创建bean的方法。
具体案例:
package com.dong.JavaConfig;
public class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.dong.JavaConfig;
public class Teacher {
private Student student;
private String name;
private int age;
public Teacher(Student student, String name, int age) {
this.student = student;
this.name = name;
this.age = age;
}
public void toSay() {
System.out.println("the studnet name is " + student.getName());
}
}
package com.dong.JavaConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class TeacherConfig {
@Bean
public Student student() {
Student student = new Student();
student.setAge(10);
student.setName("liuxi");
return student;
}
@Bean
public Teacher teacher(Student student) {
return new Teacher(student,"liudong",24);
}
}
package com.dong.JavaConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* 运行结果:
* com.dong.JavaConfig.Student@4d826d77
* the studnet name is liuxi
* @author liuD
*/
public class Start {
public static void main(String args[]) {
ApplicationContext context = new AnnotationConfigApplicationContext(com.dong.JavaConfig.TeacherConfig.class);
Teacher teacher = (Teacher) context.getBean("teacher");
Student student = (Student) context.getBean("student");
System.out.println(student);
teacher.toSay();
}
}
3.XML进行配置
创建xxx.xml文件,名字可以自定义,注意<beans>标签里的声明。
<bean>标签进行bean的创建,bean标签中的 id 参数为 bean名, class 参数为需要创建bean的类的全类名;
<property>标签为属性设置值,name为属性,value为预设值,可以使用p-命名空间来简化property的注入过程;
<constructor-arg> 使用构造器来实现注入,可以使用c-命名空间来简化构造器注入的过程。
具体案例:
package com.dong.Xml;
public class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
package com.dong.Xml;
import java.util.Iterator;
import java.util.List;
public class Teacher {
private String name;
private List<Student> students;
public Teacher(String name, List<Student> students) {
super();
this.name = name;
this.students = students;
}
public void names() {
Iterator ito = students.iterator();
for(int i =0;i<students.size();i++) {
if(ito.hasNext()) {
System.out.println(ito.next().toString());
}
}
}
}
package com.dong.Xml;
public class Brother {
private Student student;
private String name;
private int age;
public Brother(Student student, String name, int age) {
this.student = student;
this.name = name;
this.age = age;
}
}
package com.dong.Xml;
public class Sister {
private String name;
private String age;
private Brother brother;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public Brother getBrother() {
return brother;
}
public void setBrother(Brother brother) {
this.brother = brother;
}
}
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"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="brother" class="com.dong.Xml.Brother">
<constructor-arg name="student" ref="student"></constructor-arg>
<constructor-arg name="name" value="刘东"></constructor-arg>
<constructor-arg name="age" value="24"></constructor-arg>
</bean>
<bean id="brother2" class="com.dong.Xml.Brother" c:name="刘X" c:age="24" c:student-ref="student" />
<bean id="sister" class="com.dong.Xml.Sister">
<property name="name" value="liulu"></property>
<property name="age" value="24"></property>
<property name="brother" ref="brother"></property>
</bean>
<bean id="sister2" class="com.dong.Xml.Sister" p:age="24" p:name="liuyulu" p:brother-ref="brother"/>
<bean id="student" class="com.dong.Xml.Student" p:age="17" p:name="刘H" />
<bean id="teacher" class="com.dong.Xml.Teacher">
<constructor-arg name="name" value="liulu"></constructor-arg>
<constructor-arg>
<list>
<ref bean="student"></ref>
</list>
</constructor-arg>
</bean>
</beans>
测试:
package com.dong.Xml;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Start {
public static void main(String args[]) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
Teacher tea = (Teacher) context.getBean("teacher");
tea.names();
}
}
部分内容参考《Spring实战》第四版