1.包扫描+组件标注注解
@Controller @service @repository @Component,这是我们常用的方式,此处不做过多描述
2.@Bean方式
首先我们有一个Person类
public class Person {
private String name;
private Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
配置类
public class MainConfig {
@Bean
public Person getPerson() {
return new Person("zhangsan", 18);
}
}
测试类:
public class IocTest {
@Test
public void test2() {
AnnotationConfigApplicationContext content = new AnnotationConfigApplicationContext(MainConfig.class);
Person person = content.getBean(Person.class);
System.out.println(person);
}
}
输出:
Person{name='zhangsan', age=18}
3.@Import相关bean注册的三种方式
1)通过@Import注入
这时候我们新建一个ImportTest 类
public class ImportTest {
}
首先我们先来看一下注入之前Bean容器中已经注入的Bean
public class MyTest {
@Test
public void main() {
AnnotationConfigApplicationContext content = new AnnotationConfigApplicationContext(MainConfig.class);
printBeans(content);
}
private void printBeans(AnnotationConfigApplicationContext context){
String[] names = context.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
}
}
这时候我们看一下输出,可以看到这时候Bean容器中注册的都是Spring自己的一些类以及我们通过注解注册的一些Bean
这时候我们通过@Import注解将我们的ImportTest类注册到Bean容器配置类中
@Import(ImportTest.class)
public class MainConfig {
@Bean
public Person getPerson() {
return new Person("zhangsan", 18);
}
}
再次查看输出情况,可以看到我们的ImportTest类被注入成功了! 这里的id默认是全类名
2)通过实现ImportSelector接口注入
首先我们定义一个SelectorTest类实现ImportSelector接口
public class SelectorTest implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[0];
}
}
并且将该类配置到配置类当中
这时候在selectImports方法中定义我们新增的两个类,Blue,Red(此处省略这两个类)
public class SelectorTest implements ImportSelector {
/**
* 返回值就是要导入到容器中的组件全类名
* @param annotationMetadata
* @return
*/
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{"com.zkk.AnnoBean.Red","com.zkk.AnnoBean.Blue"};
}
}
再次打印Bean容器中注册的类,发现我们的类被注入成功了!
3)通过实现ImportBeanDefinitionRegistrar接口注入
首先我们定义一个BeanDefinitionTest类实现ImportBeanDefinitionRegistrar接口
public class BeanDefinitionTest implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
}
}
同样将该类配置到配置类当中
这时候在registerBeanDefinitions方法中注入我们新增的类,Yellow(此处省略此类)
public class BeanDefinitionTest implements ImportBeanDefinitionRegistrar {
/**
*
* @param annotationMetadata 当前类信息
* @param beanDefinitionRegistry beanDefinition注册类
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
//判断Bean容器中有没有red跟blue这两个类
boolean red = beanDefinitionRegistry.containsBeanDefinition("com.zkk.AnnoBean.Red");
boolean blue = beanDefinitionRegistry.containsBeanDefinition("com.zkk.AnnoBean.Blue");
//如果存在red跟blue 将Yellow注入到Bean容器中
if(red&&blue){
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Yellow.class);
beanDefinitionRegistry.registerBeanDefinition("yellow",rootBeanDefinition);
}
}
}
再次查看输出:
我们可以看到yellow被注册到了Bean容器中!
4.通过Spring提供的FactoryBean(工厂Bean)
定义一个ColorFactoryBean类实现FactoryBean接口,<>中的是我们要注入的类Color(此处省略此类)
public class ColorFactoryBean implements FactoryBean<Color> {
//返回一个color对象 这个对象会被添加到容器中
@Override
public Color getObject() throws Exception {
return new Color();
}
@Override
public Class<?> getObjectType() {
return Color.class;
}
//是否是单例? true 单例 false 多实例
@Override
public boolean isSingleton() {
return true;
}
}
将ColorFactoryBean注册到配置类中:
@Import({ImportTest.class,
SelectorTest.class,
BeanDefinitionTest.class,
ColorFactoryBean.class})
public class MainConfig {
@Bean
public Person getPerson() {
return new Person("zhangsan", 18);
}
@Bean
public ColorFactoryBean colorFactoryBean () {
return new ColorFactoryBean();
}
}
打印一下Spring容器中注册的Bean,我们发现colorFactoryBean被注册到了容器中
我们打印一下Bean的类型,我们发现虽然colorFactoryBean被注册到了容器中
但是Bean的类型却是我们的Color
Object colorFactoryBean = content.getBean("colorFactoryBean");
System.out.println("bean的类型"+colorFactoryBean.getClass());
总结:默认获取到的是工厂Bean调用getObject创建的对象
当然如果想要获取工厂Bean本身也是可以的,只需要给id前边加一个&符
Object colorFactoryBean = content.getBean("&colorFactoryBean");
System.out.println("bean的类型"+colorFactoryBean.getClass());
这个时候我们在看一下控制台输出: