各位大佬光临寒舍,希望各位能赏脸给个三连,谢谢各位大佬了!!!
目录
1.三种依赖注入的方法
1.属性注入
优点
缺点
2.构造方法注入
优点
缺点
3.Setter注入
优点
缺点
4.小结
2.依赖注入常见问题的解决
1.属性注入需要的依赖的类有多个对象
1.让属性名和bean的名字相同
2.使用@Primary注解
3.使用@Qualifier注解
4.使用@Resource注解
3.@Resource和@Autowired的区别
@Autowired
@Resource
小结
4.总结
1.三种依赖注入的方法
依赖注入(Dependency Injection)也就是我们常说的DI,它是IoC思想的一种实现。DI强调的是将Spring容器中的Bean提供给需要Bean的变量。DI的实现有助于代码的解耦。注入依赖有三种不同的方法:
1.属性注入
我们可以直接在属性上方使用@Autowired注解,这样当这个对象是被交给Spring管理的对象时,它会自动为@Autowired注解的变量注入依赖对象。
@Data
public class DI {@Autowiredprivate UserInfo userInfo;
}
@Data
public class UserInfo {private String name;private Integer age;private String tele;
}
我们用下面的代码在启动类中拿到userInfo的值
ApplicationContext context=SpringApplication.run(DemoApplication.class, args);UserInfo ui=context.getBean(DI.class).getUserInfo();System.out.print(ui);
优点
属性注入简单便捷,会使代码看起来很整洁。并且当我们需要增加依赖时,直接增加一串属性和注解即可。
缺点
属性注入是不能注入final修饰的属性的,并且过度使用会使代码可读性变差。如果没有注入注入它在使用时才会出现空指针异常。
2.构造方法注入
我们可以使用构造方法来对类的属性进行依赖注入,如下:
public class DI {private UserInfo userInfo;public DI(UserInfo userInfo) {this.userInfo=userInfo;}
}
我们甚至不需要使用@Autowired,因为只有一个构造方法时,spring实例对象时必定要经过这个构造方法。但是如果有多个构造方法就要用@Autowired来表明使用那个构造方法实例对象。
优点
构造方法注入依赖时可以注入final修饰的属性,并且构造方法注入的对象没有Setter方法是不能再进行更改的。并且因为构造方法是JDK提供的,所以它的适配性好,不仅仅适配Spring框架,还可以适配其他的框架。并且依赖使用前必定会被初始化,因为构造方法是在实例对象时就会执行的。
缺点
当要注入的属性过多时,操作就会繁琐起来,并且要添加属性时就要修改构造方法,比较麻烦。
3.Setter注入
setter的原理也就是和我们平时使用setter差不多,只不过这里我们是把setter方法给到spring,让spring帮我们执行注入依赖。在使用setter时要使用注解@Autowired,很好理解在实例对象时setter方法是不会像构造方法一样自动调用的,所以要使用注解。使用方法如下:
@Controller
@Data
public class DI {private UserInfo userInfo;@Autowiredpublic void setUserInfo(UserInfo userInfo) {this.userInfo=userInfo;}
}
优点
其实没啥优点,硬要说就是它注入的依赖我们可以在后续修改,但是平时我们使用DI时基本都是把不怎么改变的对象存入容器中,如果真的要改变还不如自己new一个,改变的更方便。
缺点
缺点就是后续可以通过setter方法去改依赖,可能造成一些安全问题。
4.小结
属性注入和构造方法注入各有优点,setter没什么好说的,建议一般情况下不要使用。Spring官方推荐使用构造方法注入,但是属性注入实在是太香了,方便的很,以至于官方自己都在用。所以只能说按需使用吧。🙂
2.依赖注入常见问题的解决
说完了依赖注入的三种方法之后,我们来讲讲依赖注入常见问题的解决。
1.属性注入需要的依赖的类有多个对象
当我们使用属性注入时是直接在属性上加上@Autowired,因为@Autowired是按照类型来查找的,所以当这个类型有多个对象时,我们有时候会遇到以下问题:
我们可以看到红线标识文字所描述的,依赖只需要一个,但是spring找到了两个,怎么办呢?这时候有4种解决办法 :
1.让属性名和bean的名字相同
因为@Autowired是先找类型相同的bean,当发现有多个bean时,就根据类型名在这多个bean中找,如果找到了就使用这个bean,如果没找到就上报图错误。
这样就可以找到userInfo这个方法所返回的UserInfo的实例对象。
2.使用@Primary注解
我们可以在使用@Bean注解的方法上加上@Primary注解,表示获取依赖时,@Primary修饰的方法的返回类型如果是所需求依赖的类型,那么依赖就会注入@Primary修饰的方法返回的bean。但是这种方法很大的限制了bean的注入。因为如果只能单一的获取一个bean,那么就当我们想获取另外一个bean时就会变得很困难。使用方法如下:
3.使用@Qualifier注解
@Qualifier注解可以在@Autowired寻找到类型之后指定查找bean的名字。只要在@Qualifier的括号中写上bean的名字即可(记得带“”),这样属性名就不一定非要和bean名一样了。
在这里我们拓展一下。我上一篇五大注解存入容器中的默认名称为小驼峰(特殊情况:当首字母和第二个字母都是大写时,那么就是类型名)。而@Bean注解存入容器中默认名称就是方法名。
使用方法如下图:
4.使用@Resource注解
@Resource注解可以直接根据名称搜索bean,在@Resource的括号中写上name=“bean名”就好,当然也可以不加,那么类型名就是查找的名称。
使用方法如下图:
我们可以看到@Resource注解是不需要使用@Autowired的,这就要说到@Resource和@Autowired的区别了。
3.@Resource和@Autowired的区别
@Autowired
@Autowired是Spring提供的注解。它是根据类型来查找bean的,我们上面说过,当发现有多个bean时,就根据类型名在这多个bean中找,如果找到了就使用这个bean,没找到就报错。
@Resource
@Resource是JDK提供的注解。它是默认根据bean名称来查找bean的,也可以按照类型查找bean,都查不到就报错。
小结
@Resource和@Autowired的提供者不同,并且默认查找方式也不同。@Resource的功能更加丰富,如图:
并且它们都可以使用@Qualifier来指定名称。我们可以根据需求选择合适的注解。
4.总结
spring的依赖注入(DI)最主要的就是上述内容了,如果有缺漏,请各位大佬多多担待,可以在评论区补充一下哟!!!
制作不易,望各位大佬赏个脸,给个三连吧!!谢谢各位大佬了!!!