Spring Bean的装配
让Spring帮我们管理这些bean而不是我们自己手动去new,这样做的好处就是可以实现上下层的解耦,j2ee的开发中,我们使用某个service时都要new这个service的具体实现类,这是代码是耦合的有很强的依赖关系,通过spring bean我们可以解耦。
xml实现
配置一个applicationContext.xml文件
xml文件头是引入一些命名空间
schemaLocation 里的上下两个字符串是一组上面的一条对应相关的xmlns另一个是对应的xsd文件地址
bean里id必须是唯一的
一个bean可以有多个name,但是不能重复,如果没有id则第一个name就是默认id
有id就以id为准,没有id就以第一个name为准
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<bean id="ronan"
class="com.tzh.demo.bean.Person">
<property name="id" value="100"/>
<property name="name" value="tzh"/>
<property name="age" value="22"/>
<property name="nickname" value="ronan"/>
</bean>
</beans>
定义一个Person类
BeanNameAware,ApplicationContextAware就是Bean生命周期中的Aware三个中的两个 BeanName,BeanFactory,ApplicationContext
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Person implements BeanNameAware, ApplicationContextAware {
private int id;
private String name;
private int age;
private String nickname;
private String beanName;
private ApplicationContext applicationContext;
public void print(){
System.out.println("context.getBeanDefinitionNames()====>"
+String.join(",",applicationContext.getBeanDefinitionNames()));
}
}
用一个DemoApplication拉起整个上下文进行bean的注入
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
Person person=context.getBean(Person.class);//getBean根据类的类型进行注入时,这个类的注入必须是唯一的。不然会报Exception in thread "main" org.springframework.beans.factory.NoUniqueBeanDefinitionException
//Person person=(Person) context.getBean("ronan"); 也可以根据beanid进行注入
System.out.println(person.toString());
person.print();
}
}
自动装配实现
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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<bean name="ronan0"
class="com.tzh.demo.bean.Person">
<property name="id" value="100"/>
<property name="name" value="tzh"/>
<property name="age" value="22"/>
<property name="nickname" value="ronan"/>
</bean>
<bean name="ronan1"
class="com.tzh.demo.bean.Person">
<property name="id" value="101"/>
<property name="name" value="tzh"/>
<property name="age" value="22"/>
<property name="nickname" value="ronan"/>
</bean>
<bean id="group1" class="com.tzh.demo.bean.Group">
<property name="groupName" value="group001"/>
<property name="persons">
<list>
<ref bean="ronan0"/>
<ref bean="ronan1"/>
</list>
</property>
</bean>
<context:annotation-config />
<bean id="company" class="com.tzh.demo.bean.Company"/>
</beans>
注意开启注解 <context:annotation-config />
定义一个Group和Company类
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.Resource;
@Data
public class Company {
@Autowired(required = true)
Group group1;
@Resource(name = "ronan0")
Person person0;
public void showDetail() {
System.out.println("group1 have " + this.group1.getPersons().size() + " Persons and one is " + this.person0);
}
}
import lombok.Data;
import java.util.List;
@Data
public class Group {
private String groupName;
List<Person> persons;
public void showPersons() {
System.out.println(this.getPersons());
}
}
修改DemoApplication类测一下
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//Person person=context.getBean(Person.class);
Person person = (Person) context.getBean("ronan0");
System.out.println(person.toString());
person.print();
Group group = (Group) context.getBean(Group.class);
System.out.println(group);
group.showPersons();
Company company = (Company) context.getBean(Company.class);
System.out.println(company);
company.showDetail();
}
}
Component
定义个带Component注解的类
import lombok.Data;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Data
@ToString
@Component("person01")
public class Person {
@Value("2")
private int id;
@Value("ttzh")
private String name;
@Value("23")
private int age;
@Value("personT")
private String nickname;
}
新增一个Config类
用来扫表所有带有@Component
注解的 POJO默认是扫描当前包的路径,可以使用注解设定一种是扫描对应的包和子包还有一种是扫描多个类
package com.tzh.demo.bean.componentTest;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan(basePackages = "com.tzh.demo.bean.componentTest")
//@ComponentScan(basePackageClasses = com.tzh.demo.bean.componentTest.Person.class)
public class PersonConfig {
}
修改DemoApplication类测一下
ApplicationContext context1=new AnnotationConfigApplicationContext(PersonConfig.class);
com.tzh.demo.bean.componentTest.Person person1=(com.tzh.demo.bean.componentTest.Person)context1.getBean("person01");
System.out.println(person1.toString());
缺点
@Value不能注入对象,只能注在类上
Bean注解实现
添加一个Boss类
@Configuration
public class Boss {
@Bean(name = "Boss")
public String check() {
String str = "l'm big boss!!!";
return str;
}
}
修改DemoApplication类测一下
ApplicationContext context2=new AnnotationConfigApplicationContext("com.tzh.demo.bean");
System.out.println(context2.getBean("Boss"));
优点
可以注在方法上,能够动态获取一个 Bean 对象,能够根据环境不同得到不同的 Bean 对象