Spring bean注入方式

1.@Component注解

@Configuration@Repository@Service@Controller等注解被标注为@Component

2.@Bean注解

package com.example.demo;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author :ouruyi
 * @version 1.0
 * @date :Created in 2021/5/29 20:12
 * 功能描述:
 */
@Configuration
public class ResourceConfiguration {

    @Bean(initMethod = "init", destroyMethod = "cleanup")
    public Person person() {
        return new Person();
    }
    
}

3.@Import注解

Spring源码@Enable就是采用此方式导入bean

重点说明下@Import注解,可用于导入普通类、@Configuration类、ImportSelector接口实现类返回的全限类名、ImportBeanDefinitionRegistrar类。

3.1 导入普通类到Spring容器
package com.example.demo;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
 * @author :ouruyi
 * @version 1.0
 * @date :Created in 2021/5/29 20:12
 * 功能描述:
 */
@Configuration
@Import(Person.class)
public class ResourceConfiguration {

}

3.2 导入@Configuration类

注意:MyConfiguration类可以不用加@Configuration注解

package com.example.demo;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
 * @author :ouruyi
 * @version 1.0
 * @date :Created in 2021/5/29 20:12
 * 功能描述:
 */
@Configuration
@Import(MyConfiguration.class)
public class ResourceConfiguration {


}

package com.example.demo;

import org.springframework.context.annotation.Bean;

/**
 * @author :ouruyi
 * @version 1.0
 * @date :Created in 2021/5/29 20:24
 * 功能描述:
 */
public class MyConfiguration {

    @Bean(initMethod = "init", destroyMethod = "cleanup")
    public Person person() {
        return new Person();
    }


}


3.3 导入ImportSelector接口实现类返回的全限类名
package com.example.demo;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
 * @author :ouruyi
 * @version 1.0
 * @date :Created in 2021/5/29 20:12
 * 功能描述:
 */
@Configuration
@Import(MyImportSelector.class)
public class ResourceConfiguration {


}

package com.example.demo;

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;

import java.util.function.Predicate;

/**
 * @author :ouruyi
 * @version 1.0
 * @date :Created in 2021/5/29 20:28
 * 功能描述:
 */
public class MyImportSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{Person.class.getName()};
    }

    @Override
    public Predicate<String> getExclusionFilter() {
        return null;
    }
}

3.4 导入ImportBeanDefinitionRegistrar类。

package com.example.demo;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
 * @author :ouruyi
 * @version 1.0
 * @date :Created in 2021/5/29 20:12
 * 功能描述:
 */
@Configuration
@Import(MyImportBeanDefinitionRegistrar.class)
public class ResourceConfiguration {


}

package com.example.demo;

import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

/**
 * @author :ouruyi
 * @version 1.0
 * @date :Created in 2021/5/29 20:38
 * 功能描述:
 */
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

       @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
           BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(Person.class.getName());
           registry.registerBeanDefinition("person", beanDefinitionBuilder.getBeanDefinition());
    }
}

3.5 总结

说明:从以下@Import源码处理过程看出“导入普通类到Spring容器”和“导入@Configuration类”其实是一个东西。
org.springframework.context.annotation.ConfigurationClassParser#processImports
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
// process it as an @Configuration class

private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
			Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
			boolean checkForCircularImports) {

		if (importCandidates.isEmpty()) {
			return;
		}

		if (checkForCircularImports && isChainedImportOnStack(configClass)) {
			this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
		}
		else {
			this.importStack.push(configClass);
			try {
				for (SourceClass candidate : importCandidates) {
					if (candidate.isAssignable(ImportSelector.class)) {
						// Candidate class is an ImportSelector -> delegate to it to determine imports
						Class<?> candidateClass = candidate.loadClass();
						ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
								this.environment, this.resourceLoader, this.registry);
						Predicate<String> selectorFilter = selector.getExclusionFilter();
						if (selectorFilter != null) {
							exclusionFilter = exclusionFilter.or(selectorFilter);
						}
						if (selector instanceof DeferredImportSelector) {
							this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
						}
						else {
							String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
							Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
							processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
						}
					}
					else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
						// Candidate class is an ImportBeanDefinitionRegistrar ->
						// delegate to it to register additional bean definitions
						Class<?> candidateClass = candidate.loadClass();
						ImportBeanDefinitionRegistrar registrar =
								ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
										this.environment, this.resourceLoader, this.registry);
						configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
					}
					else {
						// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
						// process it as an @Configuration class
						this.importStack.registerImport(
								currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
						processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
					}
				}
			}
			catch (BeanDefinitionStoreException ex) {
				throw ex;
			}
			catch (Throwable ex) {
				throw new BeanDefinitionStoreException(
						"Failed to process import candidates for configuration class [" +
						configClass.getMetadata().getClassName() + "]", ex);
			}
			finally {
				this.importStack.pop();
			}
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搬山境KL攻城狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值