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实战》第四版