spring的几种注入方式

在spring中,我个人认为依赖注入的方式有3种,分别是通过属性filed注入、构造方法注入、set方法注入。接下来通过代码具体分析一下。

1、属性filed注入

@Autowired加在属性上,采用的是filed反射注入。

    @Component
    public class StayService {
    
    	@Autowired
    	private StayDao stayDao;
    
    	public void setStayDao(StayDao stayDao) {
    		System.out.println("-----set-------");
    	}
    
    	public void query(){
    		System.out.println(stayDao);
    	}
    }

在上面的代码中。当我们向IndexDao中注入IndexService时,会去Spring容器中共寻找IndexService这个类型的bean,寻找的方式一般是根据byType,再byName去找。所以ByType和ByName再这里只是我们寻找bean的一主方式。它的注入是通过filed.set来注入的,而不是通过set方法。

public class Test {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext acc = new AnnotationConfigApplicationContext(AppConfig.class);
		StayService service = acc.getBean(StayService.class);
		service.query();
	}
}

spring的几种注入方式_第1张图片
这里根本没有调用set方法,但是stayDao这已经有值了(没有打印set方法里的字符串)。所以这里是通过filed.set反射注入进来的。

2、构造方法注入

@Autowired加在构造方法上(也可以不加@Autowired注解)通过构造方法注入。

@Component
public class StayService {

//	@Autowired
	private StayDao stayDao;

	@Autowired
	public StayService(StayDao stayDao){
		this.stayDao = stayDao;
		System.out.println("构造方法 "+this.stayDao);
	}


	public void setStayDao(StayDao stayDao) {
		System.out.println("-----set-------");
	}

//	public void query(){
//		System.out.println(stayDao);
//	}

}

打印结果
spring的几种注入方式_第2张图片

3、set方法注入

@Autowired加在set方法上采用的是set方法反射注入。

@Component
public class StayService {

	private StayDao stayDao;

	@Autowired
	public void setStayDao(StayDao stayDao) {
		System.out.println("-----set-------"+stayDao);
	}
}

打印结果
spring的几种注入方式_第3张图片
这里跟set方法的名字没有任何关系,方法名字可以随便取。参数类型符合就行。

扩展

假设我们需要开发一个中间件,类似于MyBatis的。来看一下下面的这段代码。

//1、需要把StayService动态加载到Spring容器```
public class StayService {
    //2、需要把StayDao注入到StayService
	private StayDao stayDao;

	public void setStayDao(StayDao stayDao) {
		System.out.println("-----set-------"+stayDao);
	}
}

因为这里是模拟开发中间件,所以我们不能依赖Spring,也就是不能使用@Component和@Autowired注解将他们注入进来。我们先来考虑在不使用@Autowired注解的情况下如何将StayDao注入到StayService中来。

1、假设StayService已经存在容器中

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		GenericBeanDefinition stayService = (GenericBeanDefinition)beanFactory.getBeanDefinition("stayService");
		stayService.setAutowireMode(2);
	}
}

这里我将StayService的BeanDefinition取出来,将它的AutowireMode模式设置为了2,2代表通过set方法注入,它会去寻找writeMethod,也就是以set开头,符合spring定义的规则的方法,这里会找到setStayDao方法将StayDao注入进来。当然实现的方式有很多种,这只是其中一种。打印结果如下。
spring的几种注入方式_第4张图片
2、不依赖spring将StayService放入Spring容器中,并注入StayDao。

public class MyRegistrar implements ImportBeanDefinitionRegistrar {

	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(StayService.class).getBeanDefinition();
		beanDefinition.setAutowireMode(2);
		registry.registerBeanDefinition("stayService",beanDefinition);
	}
}

通过实现ImportBeanDefinitionRegistrar拿到注册器,将类转换为beanDefinition并修改setAutowireMode,再将它注入到spring容器中。如果仅仅只是还是不行的。我们还需要借助@Import注解将MyRegistrar这个类交给spring去解析。

@Configuration
@ComponentScan("com")
@Import(MyRegistrar.class)
public class AppConfig {
}

打印结果:
spring的几种注入方式_第5张图片

你可能感兴趣的:(spring)