Spring依赖注入的三种实现方式

    xiaoxiao2021-03-25  65

    依赖注入定义:

    组件依赖于抽象,当组件要与具体实现类产生依赖,则通过抽象注入实际对象。组件和具体实现类的关系由抽象进行中转。

    XXX 注入 XXX

    注入具体实现类

    通过抽象注入具体实现类。

     

    依赖注入的三种方式: 1、接口注入:一般定义一个接口,逻辑类实现该接口和该接口定义的方法, 在必须实现的方法中通过抽象类注入具体实现类。

    2、set注入:通过set方法,set某一个具体实现类,或者在xml配置文件中配置。

    3、构造器注入:在接受注入的类中定义一个构造方法,并在参数中定义需要注入的元素。构造器注入的xml配置和set注入有写区别。

     

    详细说明各种注入:

    (一)接口注入:

    1、具体类的抽象类

    2、具体实现类

    3、注入类(注入类接口,注入类实现接口的方法)

    4、测试类,new一个注入类,调用实现的方法。

    实例代码:

    具体类的抽象类

     

    package com.gc.impl; //编写接口,实现依赖抽象 public interface DataBase { public abstract void getDataBase(); }

    实现具体类

     

     

    package com.gc.acion; import com.gc.impl.DataBase; public class OracleDataBase implements DataBase{ @Override public void getDataBase() { // TODO Auto-generated method stub //oracle获取数据的方法 } }

     

    package com.gc.acion; import com.gc.impl.DataBase; public class DB2DataBase implements DataBase{ @Override public void getDataBase() { // TODO Auto-generated method stub //db2获取数据的方法 } }

    定义注入类接口,所有实现该接口的类都必须实现抽象方法,从而达到注入的目的。

     

     

    package com.gc.impl; //接口注入,通过实现该接口中所有的方法,给所有实现该接口的类都注入了DataBase的实现类 public interface IDataBaseBusinnes { public abstract void creatDI(DataBase dataBase); }

    注入类的实现

     

     

    package com.gc.acion; import com.gc.impl.DataBase; import com.gc.impl.IDataBaseBusinnes; //业务逻辑层,获取数据时通过接口进行编程,而不是具体类(实现依赖抽象即业务逻辑实现类通过抽象的接口去编写,而不是抽象依赖实现) public class DataBaseBusinnes implements IDataBaseBusinnes{ private DataBase dataBase = null; //根据注入的数据库类获取具体的数据库数据 public DataBase getDataBase(){ return dataBase; } //接口注入 @Override public void creatDI(DataBase dataBase) { // TODO Auto-generated method stub } }

    测试类:

     

    new DataBaseBusinnes

     

    package com.gc.test; import com.gc.acion.DataBaseBusinnes; import com.gc.acion.OracleDataBase; public class DataBaseTest { public static void main(String[] args) { DataBaseBusinnes dbbussinnes = new DataBaseBusinnes(); //接口注入 dbbussinnes.creatDI(new OracleDataBase()); dbbussinnes.getDataBase(); } }

     

     

     

    (二)set注入:

    可以通过配置文件注入也可以不通过配置文件注入:

    具体实现类的抽象类:

     

    package com.gc.impl; //编写接口,实现依赖抽象 public interface DataBase { public abstract void getDataBase(); }

     

     

    具体实现类:

     

    package com.gc.acion; import com.gc.impl.DataBase; public class OracleDataBase implements DataBase{ @Override public void getDataBase() { // TODO Auto-generated method stub //oracle获取数据的方法 } }

     

    package com.gc.acion; import com.gc.impl.DataBase; public class DB2DataBase implements DataBase{ @Override public void getDataBase() { // TODO Auto-generated method stub //db2获取数据的方法 } }

    注入类:通过set方法抽象注入DataBase

     

     

    package com.gc.acion; import com.gc.impl.DataBase; //业务逻辑层,获取数据时通过接口进行编程,而不是具体类(实现依赖抽象即业务逻辑实现类通过抽象的接口去编写,而不是抽象依赖实现) public class DataBaseBusinnes{ private DataBase dataBase = null; //根据注入的数据库类获取具体的数据库数据 public DataBase getDataBase(){ return dataBase; } //set注入 public void setDataBase(DataBase dataBase){ this.dataBase = dataBase; } }

     

     

    测试类:set注入

    dbbussinnes.setDataBase(new OracleDataBase());

     

    package com.gc.test; import com.gc.acion.DataBaseBusinnes; import com.gc.acion.OracleDataBase; public class DataBaseTest { public static void main(String[] args) { DataBaseBusinnes dbbussinnes = new DataBaseBusinnes(); dbbussinnes.setDataBase(new OracleDataBase()); dbbussinnes.getDataBase(); } }

    有一种情况是

    dbbussinnes.setDataBase(new OracleDataBase());

    set方法是不要的,在配置文件里给DataBase指向具体的实现得到bean,再通过这个bean类的方法getDataBase();

     

     

    这种就是通过配置文件注入,更方便

     

    (三)构造函数注入

    可以通过配置文件的方法注入和不通过配置文件的方式注入

    具体实现类的抽象类

     

    package com.gc.impl; //编写接口,实现依赖抽象 public interface DataBase { public abstract void getDataBase(); }

    具体实现类

     

     

    package com.gc.acion; import com.gc.impl.DataBase; public class OracleDataBase implements DataBase{ @Override public void getDataBase() { // TODO Auto-generated method stub //oracle获取数据的方法 } }

     

    package com.gc.acion; import com.gc.impl.DataBase; public class DB2DataBase implements DataBase{ @Override public void getDataBase() { // TODO Auto-generated method stub //db2获取数据的方法 } }

    注入类

     

     

    package com.gc.acion; import com.gc.impl.DataBase; //业务逻辑层,获取数据时通过接口进行编程,而不是具体类(实现依赖抽象即业务逻辑实现类通过抽象的接口去编写,而不是抽象依赖实现) public class DataBaseBusinnes{ private DataBase dataBase = null; //构造函数 public DataBaseBusinnes(DataBase dataBase){ this.dataBase = dataBase; } //根据注入的数据库类获取具体的数据库数据 public DataBase getDataBase(){ return dataBase; } }

    测试类

     

     

    package com.gc.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; import com.gc.acion.DataBaseBusinnes; import com.gc.acion.OracleDataBase; public class DataBaseTest { public static void main(String[] args) { //不通过配置文件的方式注入 //DataBaseBusinnes dbbussinnes = new DataBaseBusinnes(new OracleDataBase()); //通过配置文件的方式注入 ApplicationContext context = new FileSystemXmlApplicationContext("config.xml"); DataBaseBusinnes dbbussinnes = (DataBaseBusinnes)context.getBean("DataBase"); dbbussinnes.getDataBase(); } }

    构造函数的xml配置:

     

     

    <!-- 构造函数注入 ,constructor-arg表示通过构造函数注入的方式注入,index="0"表示构造函数的第一个参数,如果只有一个参数可省略--> <bean id="DataBase" class="com.gc.acion.OracleDataBase"> <constructor-arg index="0"> <value>OracleDataBase</value> </constructor-arg> </bean>

    以上三种方式的不同均在注入类的注入方式不同,有通过接口的,有通过set方法的,有通过构造函数的。

     

     

    关于选用哪种注入方式的问题,构造注入是在对象创建时期就完成注入,set注入的方式是在创建对象完成后进行注入。一般使用set注入会稍微多一些。

     

     

     

     

     

    转载请注明原文地址: https://ju.6miu.com/read-36206.html

    最新回复(0)