Spring笔记之一:依赖注入的方式属性注入和构造函数注入

1、什么是控制反转和依赖注入:

    在传统的程序设计中,调用亲自创建被调用者的实例,即由程序控制“对象之间的依赖关系”,这种方式的耦合度比较高;控制反转就是将由程序控制的“对象间的依赖关系”转交给Ioc容器来进行控制,被调用者的实例创建工作不再是调用者完成, 大大降低了调用者和被调用者之间的关系。Ioc(inversion of control:控制反转)和Di(dependency Injection:依赖注入) 是相同的概念。

2、实现依赖注入的方式:

2.1、属性注入:

 //bean类  被关联
    package com.liu.spring;
    public class RefBean {
        private String meg;
        public String getMeg() {
            return meg;
        }
        public void setMeg(String meg) {
            this.meg = meg;
        }
    }
    //bean 将关联RefBean类
    package com.liu.spring;
    public class MessageBean {
        private String message;
        private RefBean refBean;//关联的RefBean类
        public String getMessage() {
            return message;
        }
        public void setMessage(String message) {
            this.message = message;
        }
        public RefBean getRefBean() {
            return refBean;
        }
        public void setRefBean(RefBean refBean) {
            this.refBean = refBean;
        }
    }
  //配置文件
    
        
        
            
                我是属性注入方式实现的(我在RefBean类中)
            
        
        
        
            
                Spring框架(我是在MessageBean类中)
            
            
            
                
            
        
    
  //测试类
    package com.liu.action;
    public class Action_01 {    
        public static void main(String[] args) {
            //加载配置文件
            ClassPathResource resource=new ClassPathResource("applicationContext.xml");
            //创建bean工厂
            BeanFactory factory=new XmlBeanFactory(resource);
            //获取对用的实例(就避免的new对象)
            MessageBean message=(MessageBean) factory.getBean("messageBean");
            //打印结果
            System.out.println(message.getMessage()+","+message.getRefBean().getMeg());
        }
    }
    //最终的结果是
    Spring框架(我是在MessageBean类中),我是属性注入方式实现的(我在RefBean类中)

2.2、构造方法注入:

注:只需在被关联的类中写好构造函数,在配置文件之中写好配置文件就行
    //配置文件写法
     
         
         
             Spring框架(我是在MessageBean类中)
         
         
             
             
         
     
     
     
        
            我是属性注入方式实现的(我在RefBean类中)
        
        

2.3、构造注入须知:

    为了避免现在的配置文件的歧义而引起的张冠李戴,在bean中存在多个构造函数时,使用显示指定index和type属性
    比较直观。

2.4、属性注入和构造注入的比较:

    2.4.1、属性注入的特点是不需要知道属性的类型,但是必须知道属性的名称;使用set()方法实现依赖注入
    2.4.2、构造函数注入的特点是不需要知道参数的名称,不需要知道set(),但是必须知道参数的序号和类型,必须定义包含不同参数
                的构造函数。
    2.4.3、构造函数注入和属性注入方式各有优缺点。

3、循环依赖问题:

    3.1、什么是循环依赖:

                    spring容器能够顺利实例化以构造函数注入的方式配置的Bean有一个前提:Bean引用的构造函数入参引用的对象必须已近准备就绪。由于这种机制,如果两个bean都采用构造函数注入,而且都是通过构造函数入参引用对方,就会发生死锁,就是依赖循环。

          实体类如下:
//Boss类
        package com.liu.spring;
        public class Boss {    
            private String name;
            private Car car;
            public String getName() {
                return name;
            }
            public void setName(String name) {
                this.name = name;
            }
            public Car getCar() {
                return car;
            }
            public void setCar(Car car) {
                this.car = car;
            }
            //构造函数
            public Boss(String name, Car car) {
                super();
                this.name = name;
                this.car = car;
            }
        }
        //car类
        package com.liu.spring;
        public class Car {
            private String brand;
            private Boss boss;
            public String getBrand() {
                return brand;
            }
            public void setBrand(String brand) {
                this.brand = brand;
            }
            public Boss getBoss() {
                return boss;
            }
            public void setBoss(Boss boss) {
                this.boss = boss;
            }
            //构造函数
            public Car(String brand, Boss boss) {
                super();
                this.brand = brand;
                this.boss = boss;
            }
        }
   //配置文件
        
        
            
                我是劳斯莱斯(来之car类)
            
            
                
            
        
        
            
                我是刘明(来之boss类)
            
            
                
            
        
        异常为:Exception in thread "main" org.springframework.beans.factory.BeanCreationException:

    3.2、循环依赖解决方法(配置文件使用属性注入)

 
        
            
                我是劳斯拉斯(来之car类)
            
            
                
            
        
        
            
                我是不知道(来之boss类)
            
            
                
            
        
        ------测试类------------------
        //加载配置文件
        ClassPathResource resource=new ClassPathResource("applicationContext.xml");
        //创建bean工厂
        BeanFactory factory=new XmlBeanFactory(resource);
        //获得对应的实体类
        Car car=(Car) factory.getBean("car");
        Boss boss=(Boss) factory.getBean("boss");
        System.out.println(car.getBrand()+"========"+car.getBoss().getName());
        System.out.println(boss.getName()+"======="+boss.getCar().getBrand());
        最后的结果是:
        我是劳斯拉斯(来之car类)========我是不知道(来之boss类)
        我是不知道(来之boss类)=======我是劳斯拉斯(来之car类)

你可能感兴趣的:(spring)