@Autowired还可以这么用

引子

最近想着留点笔记,所以留在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

结尾

本文主要为本人的备忘,也希望给学习相关知识的朋友一点参考。因个人能力有限,文中难免会出现错漏,希望看到这篇文章的朋友能够不吝赐教。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值