Spring DI:
名词解释:依赖注入,是对IOC概念的不同角度的描述,是指应用程序在运行时, 每一个bean对象都依赖IOC容器注入当前bean对象所需要的另外一个bean 对象。(例如在MyBatis整合Spring时,SqlSessionFactoryBean 依赖IOC容器注入一个 DataSource数据源bean)
Spring DI的实现方法:
- 构造注入(通过构造方法进行粘合 )
<!--===================构造注入(基本类型与String)=========================--><bean id="student" class="com.apesource.common.Student"><!--di步骤二--><constructor-arg name="sname" value="王国祥"></constructor-arg><constructor-arg name="sage" value="21"></constructor-arg></bean> <!--===================构造注入(javaBean)=========================--><bean id="controllerImp" class="com.apesource.controller.UserControllerImp"><constructor-arg name="service" ref="serviceImp"></constructor-arg></bean><bean id="serviceImp" class="com.apesource.service.UserServiceImp"><constructor-arg name="dao" ref="daoImp"></constructor-arg></bean><bean id="daoImp" class="com.apesource.dao.UserDaoImp"></bean>
- set注入(通过set方法进行粘合)
<!--===================set注入(基本类型与String)=========================--><bean id="student" class="com.apesource.common.Student"><property name="sname" value="牛牛"></property><property name="sage" value="18"></property></bean> <!--===================set注入(javaBean)=========================--><bean id="controllerImp" class="com.apesource.controller.UserControllerImp"><property name="service" ref="serviceImp"></property></bean><bean id="serviceImp" class="com.apesource.service.UserServiceImp"><property name="dao" ref="daoImp"></property></bean><bean id="daoImp" class="com.apesource.dao.UserDaoImp"></bean> <!--===================set注入(复杂类型)=========================--><bean id="teacher" class="com.apesource.common.Teacher"><property name="mylist"><list><value>米饭</value><value>面条</value><value>香锅</value><value>冒菜</value><value>烧烤</value></list></property><property name="myset"><set><value>唱</value><value>跳</value><value>rap</value><value>篮球</value></set></property><property name="myarray"><array><value>山西</value><value>河北</value><value>山东</value><value>河南</value></array></property><property name="mymap"><map><entry key="中国" value="北京"></entry><entry key="美国" value="华盛顿"></entry><entry key="俄罗斯" value="莫斯科"></entry></map></property><property name="prop"><props><prop key="牛逼">10000</prop><prop key="vsus">10000</prop></props></property></bean>
-
属性注入(属性注入不推荐)
不推荐使用属性注入(即直接在属性上使用 `@Autowired` 注解)主要有以下几个原因:
1. 封装性破坏:属性注入通常涉及将类成员设置为非私有(通常是包级私有),这违反了封装原则。相比之下,构造注入或者set注入允许保持字段的私有性。
2. 隐式依赖:属性注入导致依赖关系不够明显。使用构造注入时,所有必需的依赖项都会在创建对象时显式提供,这使得依赖关系更加清晰。
3. 测试困难:属性注入可能使单元测试变得更加困难,因为没有简单的方法在不启动整个 Spring 上下文的情况下注入依赖。而构造器注入使得在测试时通过构造器手动注入依赖变得容易。
4. 不可变性和线程安全:通过构造注入,可以将依赖项声明为 `final`,这意味着一旦对象被创建,这些依赖项就不能被更改。这有助于创建不可变和线程安全的对象。
5. 顺序和优先级问题:使用属性注入时,Spring 容器必须先实例化类,然后才能注入依赖项。在某些情况下,这可能导致依赖项的注入顺序问题。
总而言之,尽管属性注入在某些情况下看起来更方便快捷,但构造注入或者set注入提供了更好的封装性、更清晰的依赖关系、更容易的测试以及更好的不可变性和线程安全性。因此,在实践中,建议优先考虑使用构造注入或set注入。
DI数据类型:
- 注入基本类型与String
- 注入JavaBean
- 注入复杂类型(构造注入不支持)
DI实现步骤:
1.思考,用什么方式?注入什么数据?
2.提供对应(构造,set)方法
public Student(String sname, int sage) {this .sname = sname;this .sage = sage;}
3.配置
<constructor-arg 属性名="属性值"></constructor-arg>
属性名:
name=======>参数名
index======>参数索引
type=======>参数类型
value======>参数具体数据
ref========>参数数据的引用