引子
最近想着留点笔记,所以留在blog,也可以加深一下自己的印象
IOC(Inversion of Control)控制反转是spring的核心之一。Autowired作为最常用的几个注解之一,一定不陌生,通过@Autowired可以很方便的将spring容器管理Bean注入到我们需要的地方。
看了@Autowired源码来对它的用法做个总结
总结
最常用的用法
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private ProductService productService;
}
或配合Qualifier实现不同实现类的注入
public class OrderServiceImpl implements OrderService {
@Autowired
@Qualifier("selfSupportProductServiceImpl")
private ProductService selfSupportProductService;
@Autowired
@Qualifier("generalProductServiceImpl")
private ProductService generalProductService;
}
当我们进入Autowired的源码:
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
/**
* Declares whether the annotated dependency is required.
* <p>Defaults to {@code true}.
*/
boolean required() default true;
}
可以看到@Target除了FIELD,@Autowired几乎可以用在各个地方,那么这些地方到底怎么用呢?我们直接上代码demo
首先CONSTRUCTOR:
上面的注入我们可以写成这样:
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
public OrderServiceImpl(@Qualifier("generalProductServiceImpl") ProductService productService){
this.productService = productService;
}
private ProductService productService;
}
METHOD,在方法注入我们可以这样:
@Service
public class OrderServiceImpl implements OrderService {
private ProductService productService;
@Autowired
public void setProductService(ProductService productService) {
this.productService = productService;
}
}
//在一些工具型类需要写静态方法需要使用其他对象的时候使用方法注入就很方便
@Component
public class DepartmentUtil {
private static LoadingCache departmentCache;
@Autowired
public void setDepartmentCache(@Qualifier("departmentCache") LoadingCache departmentCache){
DepartmentUtil.departmentCache = departmentCache;
}
public static String getParentDepartmentCode(String departmentCode){
// use cache do something ......
departmentCache.get(departmentCode);
//此处省略1万行
return null;
}
}
// 也可以通过方法注入实现你自己需要的一些复杂逻辑
@Service
public class OrderServiceImpl implements OrderService {
private Map<String, Map<String,String>> aComplicatedMap;
@Autowired
private void autowiredMap(){
// 此处省略一万行复杂处理
this.aComplicatedMap = new HashMap<>();
}
}
PARAMETER,用在参数上:
@Service
public class OrderServiceImpl implements OrderService {
private ProductService productService;
// 达到的效果跟用在构造器上是一样的
public OrderServiceImpl(@Autowired ProductService productService) {
this.productService = productService;
}
}
最后补充一下FIELD使用的更多用法:
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private List<SomeFilter> filters;
}
如果你debug调试一下,你会发现这里的List用的是ArrayList,那么我们能否控制对象在List中的顺序呢?答案当然是肯定的:
先看org.springframework.core.annotation.Order
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Documented
public @interface Order {
int value() default 2147483647;
}
这个注解的value()为一个int,这个int就可以定义spring容器中bean的执行优先级了,默认为最低
例如我要让filter顺序为Filter3->Filter2->Filter1:
@Service
@Order(0)
public class Filter3 implements SomeFilter {
}
@Service
@Order(99)
public class Filter2 implements SomeFilter {
}
我们可以看到顺序已经变更为3-2-1了,类似的@Autowired也可以用在数组类型的Field上,跟List类似这里就不啰嗦了
既然可以通过接口注入到List中,那么我们能否注入到Map中呢?接着我们的验证:
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private Map<String, SomeFilter> filters;
@Override
public void forEach() {
filters.forEach((k,v)->{
System.out.println(k);
System.out.println(v);
});
}
}
猜猜如果可以注入的话map的key是什么呢?Map的类型又会是什么呢?
好了,我们可以发现Map的key就是我们spring容器中bean的名称,而Map的类型为LinkedHashMap
结尾
本文主要为本人的备忘,也希望给学习相关知识的朋友一点参考。因个人能力有限,文中难免会出现错漏,希望看到这篇文章的朋友能够不吝赐教。