目录
1.1 注解@Component表明bean会被扫描到IoC容器
1.2 注解@ComponentScan定义bean被扫描策略
1.3 注解@Bean装备bean,也可以自定义第三方bean
1.装备bean
1.1 注解@Component表明bean会被扫描到IoC容器
//@Component("studentComp") //表明被扫描到IoC容器,并指定bean名称
@Component // IoC自动将类名作为bean名称,且将第一个字母改为小写
public class Student extends People {
private static final long serialVersionUID = 4043318722026127650L;
// @Value("8")//指定默认值
private int grade;
}
1.2 注解@ComponentScan定义bean被扫描策略
@Configuration
@ComponentScan // 扫描当前报及子包
@ComponentScan("com.zyf.springIoC.pojo") // 扫描指定包
@ComponentScan("com.zyf.springIoC.*") // 扫描指定包,可用通配符*,会扫描其子包
@ComponentScan(basePackages = { "com.zyf.springIoC.pojo" }) // 指定扫描基础包,会扫描其子包
@ComponentScan(basePackageClasses = { Student.class }) // 指定类
public class PojoConfigStudent {
}
1.3 注解@Bean装备bean,也可以自定义第三方bean
@Configuration // 表明该类是一个配置类
public class PojoConfig {
/**
* 使用@Bean的方式装备到IoC容器中,此方法可用于自定义第三方bean。
* 因为我们不可能去第三方的代码里加@Component或@Service的注解。
*/
@Bean(name = "peopleBean") // 方法返回的实例装备到SpringIoC容器中。给bean命名。
// @Bean //bean的名称默认为方法名,首字母变成小写
public People initPeople() {
People people = new People();
people.setId(1);
people.setName("zhangsan");
people.setNote("测试SpringIoC配置bean");
return people;
}
}
1.4 测试装备bean
@SpringBootApplication
public class SpringIoCApplication {
public static void main(String[] args) {
SpringApplication.run(SpringIoCApplication.class, args);
ApplicationContext ac = new AnnotationConfigApplicationContext(PojoConfig.class);
People people = ac.getBean(People.class);
System.out.println(people.getNote());
People people1 = (People) ac.getBean("peopleBean");
System.out.println("people与people1是否为同一个对象:" + (people == people1));
// bean默认为单例,isSingleton()返回true
System.out.println("peopleBean isSingleton = " + ac.isSingleton("peopleBean"));
System.out.println("peopleBean isPrototype = " + ac.isPrototype("peopleBean"));
ApplicationContext ac2 = new AnnotationConfigApplicationContext(PojoConfigStudent.class);
Student student = ac2.getBean(Student.class);
System.out.println(student);
// System.out.println("studentComp = " + ac2.getBean("studentComp"));
System.out.println("student = " + ac2.getBean("student"));
}
}
输出控制台:
测试SpringIoC配置bean
people与people1是否为同一个对象:true
peopleBean isSingleton = true
peopleBean isPrototype = false
com.zyf.springIoC.pojo.Student@3d4d3fe7
student = com.zyf.springIoC.pojo.Student@3d4d3fe7
1.5 容器bean多例模式
容器bean默认为单例,增加注解 @Scope("prototype") 开启多例模式。
@Bean(name = "peopleBean")
@Scope("prototype") //多例模式
public People initPeople() {
People people = new People();
people.setId(1);
people.setName("zhangsan");
people.setNote("测试SpringIoC配置bean");
return people;
}
输出:people与people1是否为同一个对象:false
1.6 bean的作用域
通过@Scope来控制bean的作用域。
@Scope类型 | 使用范围 | 作用域描述 |
single | 所有spring应用 | bean的默认值,单例 |
prototype | 所有spring应用 | 原型,多例 |
session | spring web应用 | http会话 |
application | spring web应用 | web工程生命周期,可以用single来代替 |
request | spring web应用 | 单次请求 |
globalSession | spring web应用 | 在一个全局的http session中,一个bean定义对应一个实例。实践中基本不用。 |
1.7 条件装配bean
可用于根据业务逻辑来判断,是否需要增加某bean。
条件类实现Condition接口,实现matches方法,matches返回true则装配bean。
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class Conditional4People implements Condition {//要实现Condition接口
// 返回是否需要装配bean
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 增加业务逻辑....
return false;
}
}
声明bean的时候增加 @Conditional(Conditional4People.class)。
@Configuration
public class PojoConfig {
@Bean(name = "peopleBean",initMethod = "initPeople",destroyMethod="destoryPeople")
@Conditional(Conditional4People.class) //bean条件的装配,Conditional4People.matches()返回true则装配,否则不装配
public People initPeople() {
People people = new People();
people.setId(1);
return people;
}
}
获取该bean时异常:
No qualifying bean of type 'com.zyf.springIoC.pojo.People' available
说明没有转配bean,matches返回true则可正常获取该bean。
2.总结
2.1 装配bean的两种方式
方式1:@Component(表明需要被扫描到IoC容器)和@ComponentScan(扫描策略)配合装配到SpringIoC容器。
方式2:@Bean直接标明需要装配到IoC的类,可利用其给第三方类装配到IoC。
@Component和@Bean可以显式给组件命名,隐式则是将类名第一个字母改为小写后作为bean的名字。
2.2 SpringIoC的顶层接口为BeanFacotory,isSingleton(String beanName),isPrototype(String beanName) 分别用来判断是否为单例和原型。
ApplicationContext继承了BeanFacotory。
AnnotationConfigApplicationContext实现了ApplicationContext。
SpringIoC容器的bean默认为单例,@Scope("prototype") 开启多例模式。