注入bean对象到spring容器方法

一.注解方式
  1. @Bean注解: 使用在方法上,方法返回值会被注入到spring容器中,多用于第三方jar注入spring容器,bean的名称为方法名称。代码示例:
@Configuration
public class ThreadPoolConfig {

   
   @Bean
   public ThreadPoolTaskExecutor pipelineThreadPool() {
   	
   	ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
   	taskExecutor.setCorePoolSize(4);
   	taskExecutor.setMaxPoolSize(8);
   	taskExecutor.setKeepAliveSeconds(960);
   	taskExecutor.setQueueCapacity(256);
   	taskExecutor.setThreadNamePrefix("pipelineThreadPool");
   	taskExecutor.setRejectedExecutionHandler(rejectedExecutionHandler());
   	return taskExecutor;
   	
   }
   
   @Bean
   public CallerRunsPolicy rejectedExecutionHandler() {
   	return new CallerRunsPolicy();
   }
   }
  1. @Import 注解 : 可以通过此注解将第三方jar中的类注入到spring容器中,但是需要注意的是通过此注解导入的类的bean的名称为全限定类名,而通过@bean注解导入的bean的名称为方法名称。示例代码:
@Import(value = ThreadPoolTaskExecutor.class)
@Configuration
public class ThreadPoolConfig {

	/**
	 * 当 @Import 注解导入ThreadPoolTaskExecutor 时, bean的名称为org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor 
	 * @Import 注解也是用来导入第三方jar包的。
	 * @return
	 */
	//@Bean
	//@Conditional(value = EvnConditinal.class)
	public ThreadPoolTaskExecutor pipelineThreadPool() {
		
		ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
		taskExecutor.setCorePoolSize(4);
		taskExecutor.setMaxPoolSize(8);
		taskExecutor.setKeepAliveSeconds(960);
		taskExecutor.setQueueCapacity(256);
		taskExecutor.setThreadNamePrefix("pipelineThreadPool");
		taskExecutor.setRejectedExecutionHandler(rejectedExecutionHandler());
		return taskExecutor;
		
	}
	
	@Bean
	public CallerRunsPolicy rejectedExecutionHandler() {
		return new CallerRunsPolicy();
	}
	
	private static AnnotationConfigApplicationContext context;
	
	public static void main(String[] args) {
		
		context = new AnnotationConfigApplicationContext(ThreadPoolConfig.class);
		String[] beanDefinitionNames = context.getBeanDefinitionNames();
		for (String string : beanDefinitionNames) {
			System.out.println(string);
		}
	}
}
二.接口方式注入
  1. ImportSelectorImpl 实现 ImportSelector 接口,并重写selectImports方法,ImportSelectorImpl必须配合@Import注解才能将 selectImports方法返回值注入到spring 容器中。
	@Override
   public String[] selectImports(AnnotationMetadata importingClassMetadata) {
   	
   	return new String[] {"com.pdf.template.test.UserEntity"};
   }

代码:
①.ImportSelectorImpl 实现类

/**
* 测试 ImportSelector 接口注入bean到spring容器中
* @author 
*
*/
public class ImportSelectorImpl implements ImportSelector {

   @Override
   public String[] selectImports(AnnotationMetadata importingClassMetadata) {
   	
   	return new String[] {"com.pdf.template.test.UserEntity"};
   }

}

②.selectImports方法中的返回值的实现类

@Data
public class UserEntity {

	private String name;
	
	private Long userID;
}

③.测试代码

@Configuration
@Import(value = ImportSelectorImpl.class)
public class ImportSelectorImplTest {

	
	public static void main(String[] args) {
		
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ImportSelectorImplTest.class);
		String[] names = context.getBeanDefinitionNames();
		for (String string : names) {
			System.out.println(string);
		}
		
		Object bean = context.getBean("com.pdf.template.test.UserEntity");
		System.out.println(bean.toString());
	}
	
}

④.使用@Import注解测试结果:
注入bean对象到spring容器方法_第1张图片
⑤.使用扫包或者是@Bean注解形式测试结果:
注入bean对象到spring容器方法_第2张图片
注入bean对象到spring容器方法_第3张图片

总结:使用其他方式比如@Bean,扫包,@Component注解 等 方式注入ImportSelectorImpl这个类并不会将此类中的selectImports 方法返回值 UserEntity 注入到spring容器中,会将ImportSelectorImpl注入到spring容器中,使用@Import注解会将selectImports 方法的返回值注入到spring容器中,但是不会将 ImportSelectorImpl 类注入到spring容器中。

2.ImportBeanDefinitionRegistrarImpl 实现 ImportBeanDefinitionRegistrar 接口,并重写registerBeanDefinitions默认方法,可以在此方法中实现bean注入到spring容器中,需要结合@Import注解一起使用,否则无效。
①.ImportBeanDefinitionRegistrarImpl 代码编写

/**
* 实现ImportBeanDefinitionRegistrar 接口 重写registerBeanDefinitions 方法将类注入spring容器
* @author Administrator
*
*/
@Component
public class ImportBeanDefinitionRegistrarImpl implements ImportBeanDefinitionRegistrar{

   /**
    * @param importingClassMetadata	注解信息
    * @param registry					bean定义注册类,用于注解bean对象
    */
   public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
   	
   	BeanDefinition beanDefinition = new RootBeanDefinition(UserEntity.class);
   	registry.registerBeanDefinition("userEntity", beanDefinition );
   }
}

②.ImportBeanDefinitionRegistrarImplTest测试代码编写

@Configuration
//@ComponentScan
@Import(ImportBeanDefinitionRegistrarImpl.class)
public class ImportBeanDefinitionRegistrarImplTest {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ImportBeanDefinitionRegistrarImplTest.class);
		String[] names = context.getBeanDefinitionNames();
		for (String string : names) {
			System.out.println(string);
		}
	}
	
	/*@Bean
	public ImportBeanDefinitionRegistrarImpl importBeanDefinitionRegistrarImpl() {
		return new ImportBeanDefinitionRegistrarImpl();
	}*/
}

③.使用@Import注解测试结果: 通过重写的 registerBeanDefinitions 方法实现了将UserEntity类注入spring容器
注入bean对象到spring容器方法_第4张图片
④.使用@Bean、扫包等方式注入ImportBeanDefinitionRegistrarImpl 测试结果:没有将UserEntity类注入到spring容器中
注入bean对象到spring容器方法_第5张图片
总结:使用其他方式比如@Bean,扫包,@Component注解 等 方式注入ImportBeanDefinitionRegistrarImpl 这个类并并重写registerBeanDefinitions 方法不会将UserEntity 注入到spring容器中,会将ImportSelectorImpl注入到spring容器中,使用@Import注解会将**UserEntity ** 注入到spring容器中,但是不会将 **ImportBeanDefinitionRegistrarImpl ** 类注入到spring容器中。

3.FactoryBean和BeanFactory
①.FactoryBean : 注入bean到spring容器里
②.BeanFactory :从spring容器中获取bean对象
③.FactoryBeanImpl实现FactoryBean接口,重写两个方法,实现注入bean到spring容器中,可以通过@Import、@Bean、@Component扫包等方式将FactoryBeanImpl注入到spring容器中,将FactoryBeanImpl注入到spring容器中就是将UserEntity对象注入了spring容器中,需要注意的是从容器中获取的bean名称虽然为factoryBeanImpl 但是类型确实UserEntity类型的。
④. FactoryBeanImpl类代码编写

/**
* 通过实现FactoryBean接口 注入FactoryBean接口的泛型对象到spring容器中
* @author Administrator
*
*/
public class FactoryBeanImpl implements FactoryBean{

   @Override
   public UserEntity getObject() throws Exception {
   	
   	return new UserEntity();
   }

   @Override
   public Class getObjectType() {
   	
   	return UserEntity.class;
   }

}

⑤.FactoryBeanImplTest测试代码编写

@Configuration
//@ComponentScan
@Import(FactoryBeanImpl.class)
public class FactoryBeanImplTest {

   public static void main(String[] args) {
   	
   	AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(FactoryBeanImplTest.class);
   	
   	String[] names = context.getBeanDefinitionNames();
   	
   	for (String name : names) {
   		System.out.println(name);
   	}
   	
   	Object bean = context.getBean("com.pdf.template.test.FactoryBeanImpl");
   	System.out.println(bean);
   }
   
   /*@Bean
   public FactoryBeanImpl factoryBeanImpl() {
   	return new FactoryBeanImpl();
   }*/
   
}

⑥.测试结果:不管通过什么方式注入FactoryBean的实现类,最终都会将FactoryBean的泛型类型的对象注入到spring容器里。

你可能感兴趣的:(spring,java)