zoukankan      html  css  js  c++  java
  • Spring中IOC的理解

    Spring中IOC的理解

    1、什么是IOC?

    (1)控制反转。把对象创建和对象间的调用过程交给Spring进行管理。

    (2)使用IOC的目的:为了耦合度降低。


    2、IOC底层原理?

    (1)xml解析、工厂模式、反射

    (2)图解

    原始调用方式(耦合度太高,dao如果变了service也要跟着变):

     引入工厂模式解除上面两个类的耦合度(但是工厂和service出现了新的耦合):

     IOC解耦过程(进一步降低耦合度)

    第一步:xml配置文件,配置创建的对象,示例:<bean id="aaa" class="xxx.dao"></bean>

    第二步:有service和dao类,创建工厂类,示例:


    IOC接口

    1. IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
    2. Spring提供IOC容器实现两种方式:(两个接口)
      1. BeanFactory:最基本接口,供内部人员使用。加载配置文件时不会去创建对象,在获取对象或者使用对象时才去创建对象。(.getBean方法时)
      2. ApplicationContext:BeanFactory接口的一个子接口。提供了更多功能,一般由开发人员使用。加载配置文件时就会把在配置文件中对象进行创建。

      3.ApplicationContext的主要实现类(File那个类是盘里全路径,Class那个是类路径位置):

      

       


    IOC操作:Bean管理

    1、什么是Bean管理(2个操作)

      (1)Spring创建对象

      (2)Spring注入属性 

    2、Bean管理操作有两种方式

      (1)基于xml配置文件方式实现

      (2)基于注解方式实现

    IOC操作Bean管理(基于xml方式)

    1、基于xml创建对象

    <bean id="aaa" class="xxx.dao"></bean>

    bean中常用属性:

    id:唯一标识

    class:类全路径

    创建对象时,默认执行无参构造,完成对象创建。

    2、基于xml注入属性

    (1)DI:依赖注入,注入属性,是IOC一种实现

    第一种注入方式:使用set方法进行注入

      创建一个类,创建其对应set方法;

      在Spring配置文件中配置对象创建,配置属性注入,示例如下:

    <bean id="book" class="org.zhaojianhui.Spring.Book">
    <property name="name" value="我的世界"/>
    <property name="price" value="15.0"/>
    </bean>

    第二种注入方式:使用有参构造进行注入

    创建一个类,定义属性以及有参构造

    //有参构造注入
    public Book(String name, String price) {
    this.name = name;
    this.price = price;
    }

    Spring配置文件中编写:
    <bean id="book" class="org.zhaojianhui.Spring.Book">
    <constructor-arg name="name" value="我的爱人"></constructor-arg>
    <constructor-arg name="price" value="16.0"></constructor-arg>
    </bean>


    P名称空间注入(底层还是set注入):
    1、加一个p命名空间

     2、进行属性注入:


    xml中其他属性注入:
    1、空值注入
    
    
    
    2、属性值包含特殊符号:
    
    

     转义<>:&lt; &gt


    注入属性:外部Bean

    1. 创建service类和dao类,省略此处。

        2.在service中调用dao

     //创建userDao类型,申明set方法
        private UserDao userDao;
    
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    
        public void add() {
            System.out.println("service add!!!");
            userDao.update();
        }

        3.在Spring配置文件中进行配置

      <!--service和dao对象创建-->
        <bean id="userService" class="org.zhaojianhui.Spring.service.UserService">
            <!--注入userdao对象,name是类里的属性名称,
            ref是创建UserDao中bean标签的id,注入外部bean-->
            <property name="userDao" ref="userDao"></property>
        </bean>
    
        <bean id="userDao" class="org.zhaojianhui.Spring.dao.UserDaoImpl"></bean>

    注入属性:内部Bean

    1. 一对多关系:例如部门对员工示例
    //部门类
    public class Dept {
        private String dname;
    
        public void setDname(String dname) {
            this.dname = dname;
        }
    }
    //员工类
    public class Emp {
        private String name;
    
        private String gender;
    
        private Dept dept;
    
        public void setDept(Dept dept) {
            this.dept = dept;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void setGender(String gender) {
            this.gender = gender;
        }
    }

    2.在Spring配置文件中进行配置

    <!--内部bean-->
        <bean id="emp" class="org.zhaojianhui.Spring.Bean.Emp">
            <property name="name" value="zs"></property>
            <property name="gender" value="男"></property>
            <!--对象类型属性-->
            <property name="dept">
                <bean id="demp" class="org.zhaojianhui.Spring.Bean.Dept">
                    <property name="dname" value="安保部"></property>
                </bean>
            </property>
        </bean>

    级联赋值:

    写法1:

    <bean id="emp" class="org.zhaojianhui.Spring.Bean.Emp">
            <property name="name" value="zs"></property>
            <property name="gender" value="男"></property>
            <!--对象类型属性-->
            <property name="dept" ref="depts"></property>
        </bean>
        <bean id="depts" class="org.zhaojianhui.Spring.Bean.Dept">
            <property name="dname" value="安保部"></property>
        </bean>

    写法2:

    <property name="dept.dname" value="体育部"></property>,对应Emp实体需要生成dept属性的getter方法才能完成!

    IOC操作Bean管理(xml注入集合属性)
    1、注入数组类型属性


    2、注入List类型属性

    3、注入Map类型属性

    配置文件中代码示例如下:
        <!--数组、List、Map注入-->
        <bean id="stu" class="org.zhaojianhui.Spring.Bean.Stu">
            <property name="course">
                <array>
                    <value>语文</value>
                    <value>数学</value>
                </array>
            </property>
    
            <property name="list">
                <list>
                    <value>张三</value>
                    <value>三儿</value>
                </list>
            </property>
            <property name="map">
                <map>
                    <entry key="JAVA" value="java">
                    </entry>
                    <entry key="PHP" value="php"></entry>
                </map>
            </property>
        </bean>
    在集合里设置对象类型值:
     <!--注入list集合类型,值是对象-->
            <property name="courseList">
                <list>
                    <ref bean="course1"></ref>
                    <ref bean="course2"></ref>
                </list>
            </property>
        </bean>
        <bean id="course1" class="org.zhaojianhui.Spring.Bean.Course">
            <property name="cname" value="Spring"></property>
        </bean>
        <bean id="course2" class="org.zhaojianhui.Spring.Bean.Course">
            <property name="cname" value="MVC"></property>
        </bean>
    

      

    把集合注入部分提取出来

    1、在配置文件中引入一个名称空间util

    <?xml version="1.0" encoding="utf-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:util="http://www.springframework.org/schema/util"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
             http://www.springframework.org/schema/beans/spring-beans.xsd
             http://www.springframework.org/schema/util
             http://www.springframework.org/schema/util/spring-util.xsd">
    
    </beans>
    

    2、使用util标签完成list集合提取注入

     <!--提取list集合属性注入-->
        <util:list id="list">
            <value>w</value>
            <value>q</value>
            <value>r</value>
    
        </util:list>
        <!--注入使用-->
        <bean id="stu" class="org.zhaojianhui.Spring.Bean.Stu">
            <property name="list" ref="list">
            </property>
        </bean>
    

      


    IOC操作Bean管理(FactoryBean)
    1、Spring有两种Bean,一种普通Bean,另外一种工厂Bean

    2、普通Bean:在配置文件中定义Bean类型就是返回类型

    3、工厂Bean:在配置文件中定义Bean类型可以和返回类型不一样


    Bean的作用域:

    默认单例,可以在配置文件中修改作用域,在bean标签的scope属性用于设置,属性值有singleton,prototype(多例),request,session

    区别:

    设置为单例时,加载配置文件时就会创建单例对象,设置为多例时候不是在加载配置文件时创建对象,而是在调用getBean方法时候创建多实例对象。


    Bean的生命周期:

     1、通过构造器创建bean示例(无参构造)

    2、为bean的属性设置值和对其他bean的引用(调用set方法)

    把bean实例传递给bean后置处理器方法(如果使用了后置处理器就会多两个步骤,即实现BeanPostProcessor方法)

    3、调用bean的初始化方法

    把bean实例传递给bean后置处理器方法

    4、bean可以使用了(对象获取到了)

    5、当容器关闭时,调用Bean的销毁方法


    XML自动装配

    1、基于名称 2、基于类型

     <!--自动装配,bean标签属性autowire配置自动装配,byName根据属性名称注入(bean的id值和类属性名称一样),byType根据属性类型注入
        (但是相同类型的bean不能定义多个)-->
        <bean id="emp" class="org.zhaojianhui.Spring.Bean.Emp" autowire="byName"></bean>
        <bean id="dept" class="org.zhaojianhui.Spring.Bean.Dept">
            <property name="dname" value="开发部门"></property>
        </bean>
    

    引入外部属性文件(以数据库信息为例):

    1、直接配置数据库信息

    2、通过引入外部属性文件配置数据库连接池

      1、引入context命名空间

      2、spring配置文件中引入外部文件

        <!--引入外部属性文件-->
        <context:property-placeholder location="classpath:jdbc.properties"/>
    

      3、使用${属性}填充内容

     <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="driverClassName" value="${prop.driverClass}"></property>
            <property name="url" value="${prop.url}"></property>
            <property name="username" value="${prop.userName}"></property>
            <property name="password" value="${prop.password}"></property>
        </bean>
    

      


    IOC操作Bean管理(基于注解方式)

    1、什么是注解?

      1、@注解名称,注解可以作用在类、方法、属性上

      2、使用目的:简化xml配置

    2、Spring针对Bean管理中创建对象提供注解:

      1、@Component:

      2、@Service:

      3、@Controller:

      4、@Repository:用于dao层一般

    3、基于注解方式演示对象创建(注解的value值默认为类首字母小写)

    第一步:引入aop依赖

    第二步:开启组建扫描

    <!--开启组件扫描-->
        <context:component-scan base-package="org.zhaojianhui.Spring"></context:component-scan>

     开启组件扫描细节(设置哪些扫描哪些不扫描):

     <!--use-default-filters="false",表示现在不使用默认filter,自己配置filter,下面配置表示只扫描包下带有Controller注解的类-->
        <context:component-scan base-package="org.zhaojianhui.Spring" use-default-filters="false">
            <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        </context:component-scan>
    

      


    基于注解方式实现属性注入:

    (1) @Autowired:根据属性类型进行自动装配

      1、在service中注入dao对象(此时加了注解后不需要set方法)

    @Service
    public class UserService {
        @Autowired
        private UserDao userDao;
    
    
        public void add() {
            System.out.println("service add!!!");
            userDao.update();
        }
    }

    (2)@Qualifier(需要和Autoqired一起使用):根据属性名称注入

     @Autowired
        @Qualifier(value = "userDaoImp1")
        private UserDao userDao;
    

      

    (3)@Resource:可以根据名称/类型注入

     @Resource//根据类型注入
       @Resource(name = "userDaoImp1")//根据名称注入
        private UserDao userDao;

    (4)@Value:注入普通类型

    @Value(value = "abc")
        private String name;
    

      

    纯注解开发:

    (1)创建配置类,替代xml文件

    @Configuration//作为配置类,替代xml文件
    @ComponentScan(basePackages = {"org.zhaojianhui.Spring"})//需要扫描的包
    public class SpringConfig {
    }

    (2)编写测试类

    public void test() {
           // ApplicationContext appo = new ClassPathXmlApplicationContext("bean2.xml");
            ApplicationContext appo = new AnnotationConfigApplicationContext(SpringConfig.class);;//加载配置类
            UserService userService = appo.getBean("userService", UserService.class);
            System.out.println(userService);
            userService.add();
    
    
        }
    

      

  • 相关阅读:
    30、Java中Set集合之HashSet、TreeSet和EnumSet
    此地址使用了一个通常用于网络浏览以外的端口。出于安全原因,Firefox 取消了该请求。
    C# 关闭显示器(显示)
    29、java中阻塞队列
    28、队列和栈
    27、ArrayList和LinkedList的区别
    26、线性表(List)
    WMI使用的WIN32_类库名
    android 怎样加速./mk snod打包
    hdu1081 最大子矩阵
  • 原文地址:https://www.cnblogs.com/zhaojianhui/p/13455805.html
Copyright © 2011-2022 走看看