Spring之属性填充

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 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);

在这里插入图片描述

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