Spring给属性的方式一般有三种
1、通过在属性的添加@Autowired注解
@Component
public class UserService {
@Autowired
private OrderService orderService;
public void setOrderService(OrderService orderService) {
this.orderService = orderService;
}
public OrderService getOrderService() {
return this.orderService;
}
}
1、Spring在属性填充的时候,用org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessPropertyValues将类中属性使用@Autowired注解的属性查找出来。
2、同时在查找完成之后就会立刻赋值。
2、通过@Bean(autowire= Autowire.BY_NAME)
@Component
public class UserService {
private OrderService orderService;
public void setOrderService(OrderService orderService) {
this.orderService = orderService;
}
public OrderService getOrderService() {
return this.orderService;
}
}
public class OrderService {
}
@ComponentScan("com.wwh")
public class AppConfig {
@Bean(autowire= Autowire.BY_NAME)
public OrderService orderService() {
return new OrderService();
}
}
1、这种方式可以不需要在private OrderService orderService上添加属性;
2、但是必须得有setOrderService方法;
3、在定义OrderService这个Bean的时候需要使用@Bean(autowire= Autowire.BY_NAME);
4、@Bean(autowire= Autowire.BY_NAME)表示通过名字添加。
5、BY_NAME使用的是setOrderService方法的OrderService,将首字母小写,开始查找Bean或者创建Bean。
6、通过这种方式会过滤掉简单类型,比如Enum、CharSequence、八大基本类型等等,即使向单例池中注册了Bean,获取的值也会是null。
通过这种方法添加属性的源码
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 获取属性字段的名称
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
// 判断是否有这个属性字段对应的Bean或者BeanDefinfition
if (containsBean(propertyName)) {
// 创建Bean或者从单例池中获取字段对应的Bean
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
// 绑定Bean与属性对应Bean的关系
registerDependentBean(propertyName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
}
}
}
这个方法主要是通过BY_NAME找出有多少个属性需要被填充值。
3、通过@Bean(autowire= Autowire.BY_TYPE)
@Component
public class UserService {
private OrderService orderService;
public void setOrderService(OrderService orderService) {
this.orderService = orderService;
}
public OrderService getOrderService() {
return this.orderService;
}
}
public class OrderService {
}
@ComponentScan("com.wwh")
public class AppConfig {
@Bean(autowire= Autowire.BY_TYPE)
public OrderService orderService() {
return new OrderService();
}
}
1、这种方式可以不需要在private OrderService orderService上添加属性;
2、但是必须得有setOrderService方法;
3、在定义OrderService这个Bean的时候需要使用@Bean(autowire= Autowire.BY_TYPE);
4、@Bean(autowire= Autowire.BY_TYPE)表示通过名字添加。
5、BY_TYPE使用的是setOrderService方法的参数,通过将参数查找出来,创建Bean或者从单例池中把对象找出赋值。
6、通过这种方式会过滤掉简单类型,比如Enum、CharSequence、八大基本类型等等,即使向单例池中注册了Bean,获取的值也会是null。
通过这种方法添加属性的源码
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
// 获取属性字段的名称
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
// 获取属性字段描述器
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// Don't try autowiring by type for type Object: never makes sense,
// even if it technically is a unsatisfied, non-simple property.
if (Object.class != pd.getPropertyType()) {
// 获取set方法里的参数
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
// 获得参数的描述器
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
// 获得参数的值
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
// 属性填充
registerDependentBean(autowiredBeanName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
propertyName + "' to bean named '" + autowiredBeanName + "'");
}
}
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
4、三种赋值的对比。
1、在Spring源码中,第一种会在查找出来属性之后立刻赋值,第二种和第三种则是需要在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyPropertyValues这个方法中被复制。
2、假如实现了MergedBeanDefinitionPostProcessor接口,手动给这个属性赋值,最终orderService将会是用户自己设定的值。
@Component
public class SpringTestBeanPostProcessor implements MergedBeanDefinitionPostProcessor {
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (beanName.equals("userService")) {
MutablePropertyValues propertyValues = new MutablePropertyValues();
OrderService orderService = new OrderService();
System.out.println("beanPostProcessor: "+orderService);
propertyValues.addPropertyValue("orderService", orderService);
beanDefinition.setPropertyValues(propertyValues);
}
}
@Override
public void resetBeanDefinition(String beanName) {
MergedBeanDefinitionPostProcessor.super.resetBeanDefinition(beanName);
}
}
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = (UserService) applicationContext.getBean("userService");
OrderService orderService = (OrderService) applicationContext.getBean("orderService");
System.out.println("UserService OrderService: "+userService.getOrderService());
System.out.println("OrderService: "+orderService);