zoukankan      html  css  js  c++  java
  • spring--设置注入VS构造注入

    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;
            }
        }
      //配置文件
        <beans>
            <!-- 配置文件 1.先配置类为RefBean -->
            <bean id="refBean" class="com.liu.spring.RefBean">
                <property name="meg">
                    <value>我是属性注入方式实现的(我在RefBean类中)</value>
                </property>
            </bean>
            <!-- 2、再来配置类 MessageBean  -->
            <bean id="messageBean" class="com.liu.spring.MessageBean">
                <property name="message">
                    <value>Spring框架(我是在MessageBean类中)</value>
                </property>
                <!-- 加入另一个bean  -->
                <property name="refBean">
                    <ref local="refBean"/>
                </property>
            </bean>
        </beans>
      //测试类
        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、构造方法注入:
    注:只需在被关联的类中写好构造函数,在配置文件之中写好配置文件就行
        //配置文件写法
         <bean id="messageBean" class="com.liu.spring.MessageBean">
             <!--- 构造函数注入的关键标签 --->
             <constructor-arg index="0">
                 <value>Spring框架(我是在MessageBean类中)</value>
             </constructor-arg>
             <constructor-arg index="1">
                 <!-- 引用之外的bean  -->
                 <ref local="refBean"/>
             </constructor-arg>
         </bean>
         <!-- 被关联的bean类--->
         <bean id="refBean" class="com.liu.spring.RefBean">
            <property name="meg">
                <value>我是属性注入方式实现的(我在RefBean类中)</value>
            </property>
        </bean>    
    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;
                }
            }
       //配置文件
            <!-- 循环依赖问题的配置文件如下 (错) -->
            <bean id="car" class="com.liu.spring.Car"><!-- car类 -->
                <constructor-arg>
                    <value>我是劳斯莱斯(来之car类)</value>
                </constructor-arg>
                <constructor-arg>
                    <ref local="boss"/><!-- 引用boss -->
                </constructor-arg>
            </bean>
            <bean id="boss" class="com.liu.spring.Boss">
                <constructor-arg>
                    <value>我是刘明(来之boss类)</value>
                </constructor-arg>
                <constructor-arg>
                    <ref local="car"/><!-- 引用car -->
                </constructor-arg>
            </bean>
            异常为:Exception in thread "main" org.springframework.beans.factory.BeanCreationException:
        3.2、循环依赖解决方法(配置文件使用属性注入)
     <!-- 循环依赖问题的配置文件如下 (正确) -->
            <bean id="car" class="com.liu.spring.Car">
                <property name="brand">
                    <value>我是劳斯拉斯(来之car类)</value>
                </property>
                <property name="boss">
                    <ref local="boss"/>
                </property>
            </bean>
            <bean id="boss" class="com.liu.spring.Boss">
                <property name="name">
                    <value>我是不知道(来之boss类)</value>
                </property>
                <property name="car">
                    <ref local="car"/>
                </property>
            </bean>
            ------测试类------------------
            //加载配置文件
            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类)
    

      

  • 相关阅读:
    .net core EF 入门笔记Code First
    Windows环境下安装MongodDB
    Ueditor1.4.3.3 富文本编辑器在图片不显示问题
    .net IIS网站部署Host文件简单应用
    .Net初学Less的安装与部署
    EF+MVC动态Lamda表达式拼接(学习笔记二)
    EF+MVC动态Lamda表达式拼接(学习笔记)
    区块链从入门到放弃
    Unity3D的update和FixedUpdate
    忽雷太极拳十三式
  • 原文地址:https://www.cnblogs.com/ipetergo/p/6295433.html
Copyright © 2011-2022 走看看