测试同学上手Spring之DI深入解析

前面已经介绍了如何上手Spirng编码以及IOC的核心概念,今天给大家讲解Spring的另一个重点——DI。

Spring核心模块

DI概念

IoC 其实有两种方式,一种就是 DI(Dependency Injection) ,而另一种是 DL(Dependency Lookup)即依赖查找。前者是当前组件被动接受IoC容器注入的依赖组件,而后者则是组件主动去某个服务注册地查找其依赖的组件,我们这里重点介绍DI。

IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI来实现的。比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。Spring是通过反射技术实现注入的,它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性。

简单的总结一下依赖注入:

  • 依赖 : 指Bean对象的创建依赖于容器 。
  • 注入 : 指Bean对象所依赖的资源 , 由容器来设置和装配。

注入的方式主要包括Setter注入(重点)、构造器注入和参数直接注入。还有拓展方式注入,即:p命名空间注入和c命名空间注入,这里就不再展开介绍了,有兴趣的同学可以自行研究。

Setter注入

IoC 容器使用 setter 方法注入被依赖的实例。通过调用无参构造器或无参 static 工厂方法实例化 bean 后,调用该 bean的setter 方法(类中必须有属性的set方法),即可实现基于setter的DI

代码如下:

 
 
 
 
  1. public class Address { 
  2.     private String address; 
  3.     public String getAddress() { 
  4.         return address; 
  5.     } 
  6.     public void setAddress(String address) { 
  7.         this.address = address; 
  8.     } 

 
 
 
 
  1. import java.util.List; 
  2. import java.util.Map; 
  3. import java.util.Properties; 
  4. import java.util.Set; 
  5. public class Student { 
  6.     private String name; 
  7.     private Address address; 
  8.     private String[] books; 
  9.     private List hobbys; 
  10.     private Map card; 
  11.     private Set games; 
  12.     private String wife; 
  13.     private Properties info; 
  14.     public void setName(String name) { 
  15.         this.name = name; 
  16.     } 
  17.     public String getName() { 
  18.        return this.name; 
  19.     } 
  20.     public void setAddress(Address address) { 
  21.         this.address = address; 
  22.     } 
  23.    public void setBooks(String[] books) { 
  24.         this.books = books; 
  25.     } 
  26.     public void setHobbys(List hobbys) { 
  27.         this.hobbys = hobbys; 
  28.     } 
  29.     public void setCard(Map card) { 
  30.         this.card = card; 
  31.     } 
  32.     public void setGames(Set games) { 
  33.         this.games = games; 
  34.     } 
  35.     public void setWife(String wife) { 
  36.         this.wife = wife; 
  37.     } 
  38.     public void setInfo(Properties info) { 
  39.         this.info = info; 
  40.     } 
  41.     public void show(){ 
  42.         System.out.println("name="+ name 
  43.                 +",address="+ address.getAddress() 
  44.                 +",books=" 
  45.         ); 
  46.         for (String book:books){ 
  47.             System.out.print("<<"+book+">>\t"); 
  48.         } 
  49.         System.out.println("\nhobbys:"+hobbys); 
  50.         System.out.println("card:"+card); 
  51.         System.out.println("games:"+games); 
  52.         System.out.println("wife:"+wife); 
  53.         System.out.println("info:"+info); 
  54.     } 

 配置文件

 
 
 
 
  1.  
  2.       
  3.   

配置文件中把name 赋值为小明,即完成了对代码 private String name的注入。

测试类

 
 
 
 
  1. public static void main(String[] args) { 
  2.            ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); 
  3.            Student student=(Student)context.getBean("student"); 
  4.            System.out.println(student.getName()); 
  5.         } 

 运行结果,输出:小明

常见注入方式的xml 配置如下:

bean注入

使用ref进行引入其他bean

 
 
 
 
  1.  
  2.       
  3.      
  4.  

数组注入

 
 
 
 
  1.  
  2.           
  3.              数学 
  4.              语文 
  5.              英语 
  6.           
  7.      

 List注入

 
 
 
 
  1.  
  2.       
  3.          听歌 
  4.          看电影 
  5.          打游戏 
  6.       
  7.    

 Map注入

 
 
 
 
  1.  
  2.       
  3.           
  4.           
  5.       
  6.   

set注入

 
 
 
 
  1.  
  2.       
  3.          CS 
  4.          斗地主 
  5.          消消乐 
  6.       
  7.   

 Null注入

 
 
 
 
  1.  

Properties注入

 
 
 
 
  1.  
  2.       
  3.          123456 
  4.          男 
  5.          小明 
  6.       
  7.   

 测试方法

 
 
 
 
  1. public static void main(String[] args) { 
  2.            ApplicationContextcontext = new ClassPathXmlApplicationContext("bean1.xml"); 
  3.            Studentstudent=(Student)context.getBean("student"); 
  4.            student.show();  
  5.         } 

 运行结果,输出:

name=小明,address=北京,books=

<<数学>> <<语文>> <<英语>>

hobbys:[听歌, 看电影, 打游戏]

card:{招行=123456789, 工行=987654321}

games:[CS, 斗地主, 消消乐]

wife:null

info:{学号=123456, 性别=男, 姓名=小明}

构造器注入

指IoC 容器使用构造方法注入被依赖的实例。基于构造器的 DI 通过调用带参数的构造方法实现,每个参数代表一个依赖。

代码如下:

 
 
 
 
  1. public class Student2{ 
  2.        private String name; 
  3.        public Student2(String name) { 
  4.           this.name = name; 
  5.       } 
  6.        public void setName(String name) { 
  7.           this.name = name; 
  8.       } 
  9.        public void show(){ 
  10.           System.out.println("name="+ name ); 
  11.       } 
  12.     } 

 配置文件中设置

 
 
 
 
  1.   
  2.  
  3.     
  4.     
  5.  
  6.  
  7.  
  8.     
  9.     
  10.  
  11.  
  12.  
  13.     
  14.  

测试代码

 
 
 
 
  1. public static void main(String[] args) { 
  2.            ApplicationContextcontext = new ClassPathXmlApplicationContext("bean3.xml");        
  3.            Student2 user = (Student2) context.getBean("student1") 
  4.            user.show(); 
  5.         } 

 运行结果:

name=kevin1

参数直接注入

主要通过注解@Autowired、@Qualifier和@Resource来实现

@Autowired

@Autowired是按类型自动转配的,不支持id匹配。

需要导入 spring-aop的包

配置文件中设置<

context:annotation-config/>

代码:

 
 
 
 
  1. public class Animal {    
  2. @Autowired    private Cat cat; //运行时spring通过DI会把Cat类实例化    
  3. @Autowired private Dog dog;//运行时spring通过DI会把Dog类实例化    
  4.        public void printCatshot() { 
  5.               cat.shout();      
  6.   }   
  7.         public void printDogshot() { 
  8.                 dog.shout(); 

 @Qualifier

@Autowired是根据类型进行自动装配的。如果当Spring上下文中存在一个类型的不同bean时,就会抛出BeanCreationException异常;我们可以使用@Qualifier配合@Autowired来解决这些问题。

代码:

 
 
 
 
  1. @Autowired 
  2. @Qualifier(value= "dog1") 
  3. private Dog dog1; 
  4. beans.xml 
  5.  
  6.  

 @Resource

@Resource是J2EE提供的, 需导入Package: javax.annotation.Resource;

@Resource如有指定的name属性,先按该属性进行byName方式查找装配,其次再进行默认的byName方式进行装配,都不成功,则报异常。

代码

 
 
 
 
  1. @Resource(name = "dog2") 
  2. private Dog dog; 
  3. beans.xml 
  4.  
  5.  

 最简单的解释

IoC通过DI技术主要实现了以下两点:

  • 在系统运行中,动态地向某个对象提供它所需要的其他对象;
  • 在系统运行中,动态地从配置文件中读取数据来为对象的属性进行赋值。

 【编辑推荐】

  1. 跟妹妹聊到 Java 16 新特征,真香!
  2. IT项目过多,管理太难?NO!因为你还没学会这七招
  3. 学了五年Python,这些网站让我相见恨晚,快来一起见识一下
  4. Java都到16了,为什么都还在用8,是越做越烂了么?
  5. 实在太神奇!Windows10这些黑科技小功能你都用过吗

分享文章:测试同学上手Spring之DI深入解析
转载来于:http://www.shufengxianlan.com/qtweb/news42/422042.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联