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========>参数数据的引用