目录

1.xml方式

2.注解方式

2.1@Configuration + @Bean

2.2@Import

3.FactoryBean

4.BeanFactoryPostProcessor


 

1.xml方式

所有bean的注入都依靠xml文件来完成

方式有:set方法注入,构造注入,字段注入等

set方法注入实例:

<bean name="teacher" class="org.springframework.demo.model.Teacher">
    <property name="name" value="张老师"></property>
</bean>

对应实体类方法

public class Teacher {
	private String name;
	
	public void setName(String name) {
		this.name = name;
	}
}

缺点:

1.既要维护代码还要维护配置文件,开发效率低,尤其是配置文件很多的情况

2.编译期间不好排错

3.在解析xml时候,无论是将xml一次性装进内存还是一行行解析都会占用内存资源

2.注解方式

2.1@Configuration + @Bean

当我们需要引入第三方的 jar 包时,可以用 @Bean 注解来标注,同时需要搭配 @Configuration 来使用

  • @Configuration 用来声明一个配置类,可以理解为 xml 的 <beans> 标签
  • @Bean 用来声明一个 bean,将其加入到 Spring 容器中,可以理解为 xml 的 <bean> 标签
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        ......
        return redisTemplate;
    }
}

2.2@Import

作用:将第三方jar包注入Spring,但是只可以作用在类上

例如在注解 EnableSpringConfigured 上就包含了 @Import 注解,用于将  配置文SpringConfiguredConfiguration件加载进 Spring 容器。

@Import(SpringConfiguredConfiguration.class)
public @interface EnableSpringConfigured {}

当然,它里面value是一个数组可以注入多个class进容器

@Configuration
@Import(MyImportSelector.class)
public class MyConfig {}

public class MyImportSelector implements ImportSelector {
 @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{"org.springframework.demo.model.Teacher","org.springframework.demo.model.Student"};
    }
}

其中 selectImports 方法返回的数组就会通过 @Import 注解注入到 Spring 容器中。

无独有偶,ImportBeanDefinitionRegistrar 接口也为我们提供了注入 bean 的方法

比如下面就注入了我们的Teacher到Spring容器中

@Configuration
@Import(value = {MyImportBeanDefinitionRegistrar.class})
public class MyConfig {}

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
                                        BeanDefinitionRegistry registry) {
            RootBeanDefinition tDefinition = new RootBeanDefinition(Teacher.class);
            // 注册 Bean,并指定bean的名称和类型
            registry.registerBeanDefinition("teacher", tDefinition);
        }
    }
}

3.FactoryBean

说到FactoryBean,就想到了BeanFactory

BeanFactory:是IOC容器或者说对象工厂,管理所有Bean,是一个底层接口,ApplicationContext是它的子类,丰富了很多功能(国际化等等),并且BeanFactory是懒加载(要才有)

FactoryBean:它是一个Bean,是一个能够生产或者修饰对象的工程Bean,用了工厂模式和装饰器模式

3.1首先实现FactoryBean接口

public class TeacherFactoryBean implements FactoryBean<Teacher> {

	 /**
	  * 返回此工厂管理的对象实例
	  **/
	 @Override
	 public Teacher getObject() throws Exception {
	  	return new Teacher();
	 }
	
	 /**
	  * 返回此 FactoryBean 创建的对象的类型
	  **/
	 @Override
	 public Class<?> getObjectType() {
	  	return Teacher.class;
	 }

}

3.2然后通过@Configuration+@Bean的方式将TeacherFactoryBean加入容器中

@Configuration
public class MyConfig {
	 @Bean
	 public TeacherFactoryBean teacherFactoryBean(){
	  	return new TeacherFactoryBean();
	 }
}

注意:我们没有向容器中注入 Teacher,而是直接注入的 TeacherFactoryBean,然后从容器中拿 Teacher 这个类型的 bean,成功运行。

4.BeanFactoryPostProcessor

作用:BeanFactory的后置处理器,方法postProcessBeanFactory对bean进行定义并且控制

by注入 java order sql javabean注入有几种方式_by注入 java order sql

 这个registerBeanDefinition方法——>更好地使用接口来注入bean

by注入 java order sql javabean注入有几种方式_spring boot_02

 实战:

public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

	 /**
	  * 初始化过程中先执行
	  **/
	 @Override
	 public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		  RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Teacher.class);
		  //Teacher 的定义注册到spring容器中
		  registry.registerBeanDefinition("teacher", rootBeanDefinition);
	 }
	
	 /**
	  * 初始化过程中后执行
	  **/
	 @Override
	 public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {}
}

启动类代码

public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    MyBeanDefinitionRegistryPostProcessor postProcessor = new MyBeanDefinitionRegistryPostProcessor();
    // 将自定义实现类加入 Spring 容器
    context.addBeanFactoryPostProcessor(postProcessor);
    context.refresh();
    Teacher bean = context.getBean(Teacher.class);
    System.out.println(bean);
}

发现注入到Spring容器中 

org.springframework.demo.model.Teacher@2473d930