由于个人习惯,注解引入对象的时候喜欢使用@Autowired注解,很少使用@Resource。直到有次在工作中使用到模板方法模式时,使用@Autowired时出现了问题。
场景: 两个需求有可复用的代码或者代码块。
//关于类的创建声明我就不截图了,下面几行代码就说明下大致结构。
WorkBenchService AbstractWorkBench implements WorkBenchService OperationBenchServiceImpl extends AbstractWorkBench implements WorkBenchService SellWorkBenchServiceImpl extends AbstractWorkBench implements WorkBenchService
WorkBenchService是一个接口,封装了一些公用接口方法;AbstractWorkBench是一个抽象类,里面实现了两个需求可以复用的方法。对于无法复用的,方法体直接返回null,后续的逻辑由各自的业务类(OperationBenchServiceImpl、SellWorkBenchServiceImpl)来实现。进一步体会到了接口和抽象类的好处。
下面来说具体的使用吧。
最初写法
@Autowired
private WorkBenchService sellWorkBenchService;
是想先去sellWorkBenchService里面找A方法,如果有,那么就使用sellWorkBenchService里面的。如果没有那么就使用WorkBenchService的实现类AbstractWorkBench里面的。经过测试发现会报错
然后上网找了下原因,才进一步了解到
@Autowired是按照类型来匹配的(这个注解是属业spring的),如果是要按照名字匹配的话,那么需要和@Qualifier搭配使用@Qualifier("sellWorkBenchService")。
@Resource是按照name的属性注入的(这个注解属于J2EE的),如果按照name没找到的话,那么再按照bean类型去找。所以后面我就直接使用@Resource的写法了。
@Autowired默认按类型装配(这个注解是属业spring的),默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用。
@Resource装配顺序
如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;
注意一下:(1)这个name是我们在SellWorkBenchServiceImpl类上面赋值的,@Service("sellWorkBenchService")。或者是@Autowired @Qualifier("sellWorkBenchServiceImpl")这样也可以,会根据你类名的首字母小写进行匹配。
(2)使用@Resource注解的时候,若指定了具体的对象名称的话,例如@Resource(name="baseDao"),则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。
最后也是成功的解决了问题,自己平时也是喜欢封装一些方法。这样以后好复用,也好改,看上去也舒服。
附上当时参考的连接:https://blog.csdn.net/weixin_33797791/article/details/91933290