spring笔记2-IoC控制反转

IoC的概念

        控制反转(Inversion of Controller),把创建对象的权利交给框架或工厂。它包括依赖注入(DI)和依赖查找。就是把创建对象的过程交给spring框架,开发者只关注对象的使用,不关注对象创建过程。

IoC的主要作用

        解决程序间代码的耦合。

spring 的开发包

        jar包官网下载地址: JFrogicon-default.png?t=N7T8https://repo.spring.io/ui/repos/tree/General/libs-release-local/org/springframework        spring核心包的maven坐标

  <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.20.RELEASE</version>
        </dependency>
    </dependencies>

spring基于xml的IoC演示示例

        1.创建两个需要spring管理的bean

package org.example.service;

public class AccountService {
    public void run() {
        System.out.println("我是处理业务的。。。。");
    }
}
package org.example.dao;

public class AccountDao {
    public void run() {
        System.out.println("我是查数据库的。。。。");
    }
}

2.创建bean的管理配置文件,配置bean

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--    id:需要spring管理的bean的唯一标识,class:bean的类路径-->
    <bean id="accountService" class="org.example.service.AccountService"></bean>
    <bean id="acountDao" class="org.example.dao.AccountDao"></bean>
</beans>

3.调用测试

        ApplicationContext加载对象管理测试

package org.example;

import org.example.dao.AccountDao;
import org.example.service.AccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        //获取核心容器,入参为bean配置文件的路径和文件名
        ApplicationContext ac = new ClassPathXmlApplicationContext("springBean.xml");
        //根据id获取bean对象
        AccountService accountService = (AccountService) ac.getBean("accountService");
        AccountDao acountDao = (AccountDao) ac.getBean("acountDao");
        //对象调用测试
        accountService.run();
        acountDao.run();
    }
}

         BeanFactory 加载对象管理测试

public class Main {
    public static void main(String[] args) {

        //获取对象配置文件
        Resource resource = new ClassPathResource("springBean.xml");
        //加载对象配置文件
        BeanFactory factory = new XmlBeanFactory(resource);
        //根据id获取bean对象
        AccountService accountService = (AccountService) factory.getBean("accountService");
        AccountDao acountDao = (AccountDao) factory.getBean("acountDao");
        //对象调用测试
        accountService.run();
        acountDao.run();
    }
}

ApplicationContext 和 BeanFactory 的区别

        ApplicationContext:适用单例对象,构建核心容器时采用的策略是立即加载,读取完配置文件就马上创建配置文件中所有的配置的对象。

        BeanFactory :适用多例对象,延迟加载方式,在获取对象被使用对象时创建对象。

ApplicationContext 的三个常用实现类

  1.         ClassPathXmlApplicationContext : 加载类路径下的配置文件
  2.         FileSystemXmlApplicationContext : 加载磁盘任意路径下的配置文件(需要有访问权限)
  3.         AnnotationConfigApplicationContext : 读取注解创建容器

spring管理bean的细节

        spring创建bean的三种方式

                1.在spring配置文件的bean标签只配置了id和class,spring采用默认构造器创建bean对象,如果没有默认构造器,则创建失败。

                2.使用某个类中的方法或者工厂方法创建对象,并存入spring容器

                        代码示例:

···                     a.创建一个工厂方法

public class FactoryService {
   public AccountService getBean(){
       //返回没有默认构造器的类对象
       return new AccountService(true);
   }
}

                         b.修改配置


<!--    <bean id="accountService" class="org.example.service.AccountService"></bean>-->
    <!-- spring配置工厂类的管理配置-->
    <bean id="factoryService"  class="org.example.service.FactoryService"></bean>
    <!-- 指定对像需要怎么创建 factory-bean:被spring管理的工厂bean的ID,factory-method:工厂对象中返回需要spring管理的对象的方法名-->
    <bean id="accountService" factory-bean="factoryService" factory-method="getBean"></bean>

                         c.调用示例      



public class Main {
    public static void main(String[] args) {
        //获取核心容器,入参为bean配置文件的路径和文件名
       ApplicationContext ac = new ClassPathXmlApplicationContext("springBean.xml");
        //根据id获取bean对象
       AccountService accountService = (AccountService) ac.getBean("accountService");
        //对象调用测试
       accountService.run();

    }
}

                3.使用工厂中的静态方法创建对象

                        a.创建静态工厂方法

public class FactoryService {
   public static AccountService getBean(){
       //返回没有默认构造器的类对象
       return new AccountService(true);
   }
}

                b.修改配置文件

 <!-- class 指向工厂类,factory-method 获取对象的工厂方法-->
    <bean id="accountService" class="org.example.service.FactoryService" factory-method="getBean"></bean>

        bean对象的作用范围

                bean标签的 scope属性指定bean的作用范围

  •                 singleton :单例,默认
  •                 prototype : 多例
  •                 request :作用于web请求
  •                 session : 作用于web的会话范
  •                 global-session :作用于集群环境的会话范围
<bean id="acountDao" class="org.example.dao.AccountDao" scope="singleton"></bean>

                

        bean对象的生命周期

                单例对象:当容器创建时,创建对象,容器在对象就一直在,容器销毁时对象消亡

                多例对象:获取对象是框架创建对象,使用完成后,且没有别的对象引用,由java的垃圾回收器回收。

DI依赖注入 Dependenct Injection

        概念: IOC的作用通过配置依赖关系降低程序间的耦合,依赖关系的管理:以后都交给spring来维护,在当前类需要用到其他类对象时,由spring给我们提供,我们只需要在配置文件中说明,依赖关系的维护就是依赖注入。

        能注入的数据类型:

                 1.基本类型和String,使用构造函数提供

                 2.其他bean类型,使用set方法提供

                 3.复杂类型/集合类型,使用注解提供

   构造函数注入:


         标签:constructor-arg
         标签位置:bean 标签的子标签
         标签的属性:
            type:用于指定要注入数据的数据类型,和构造函数中的数据类型要一致
            index:用于给构造函数中指定位数的参数赋值,索引位置从0开始
            name:用于给构造函数中指定名称参数赋值,名称和构造函数中名称一致(常用)
            value:用于给基本数据类型和String类型赋值
            ref:用于指定对象类型参数赋值
   优势:在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功
   弊端:改变了bean对象实例化方式,使我们在创建对象时如果用不到这些数据也必须提供
   经常变化的数据不适用注入的方式。

        代码示例

        1.创建bean对象类,重载构造函数

public class AccountService {
    private String name;//String类型
    private int age;//基本数据类型
    private Date birthdy;//对象类型

    public AccountService(String name, int age, Date birthdy) {
        this.name = name;
        this.age = age;
        this.birthdy = birthdy;
    }

    public void run() {
        System.out.println("对象创建成功name=" + name + ";age=" + age + ";birthdy=" + birthdy);
    }
}

2.配置bean 注入

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

    <!--创建一个时间对象-->
    <bean id="timeObject" class="java.util.Date"></bean>

    <bean id="accountService" class="org.example.service.AccountService">
        <constructor-arg name="name" value="哈哈哈"></constructor-arg>
        <constructor-arg name="age" value="30" ></constructor-arg>
        <!-- ref 对象类型,引用其他bean,值为其他bean的ID-->
        <constructor-arg name="birthdy" ref="timeObject"></constructor-arg>
    </bean>


</beans>

3.调用示例

public class Main {
    public static void main(String[] args) {
        //获取对象配置文件
        Resource resource = new ClassPathResource("springBean.xml");
        //加载对象配置文件
        BeanFactory factory = new XmlBeanFactory(resource);
        //根据id获取bean对象
        AccountService accountService = (AccountService) factory.getBean("accountService");
        //对象调用测试
        accountService.run();

    }
}

set方法注入:

        

        标签:property
        标签位置:bean的子标签
        标签属性:
            name:用于注入时指定set的方法名称,去掉set,首字母并改成小写
            value:用于给基本数据类型和String类型赋值
            ref:用于指定对象类型参数赋值
        优势:创建对象时没有明确限制,可以直接使用默认构造函数
        弊端:有可能set方法没有执行

代码示例:

1.创建bin,给属性提供 get set方法

public class AccountService {
    private String name;
    private int age;
    private Date birthdy;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Date getBirthdy() {
        return birthdy;
    }
    public void setBirthdy(Date birthdy) {
        this.birthdy = birthdy;
    }

    public void run() {
        System.out.println("对象创建成功name=" + name + ";age=" + age + ";birthdy=" + birthdy);
    }
}

2.set方法注入配置示例

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

    <bean id="timeObject" class="java.util.Date"></bean>

    <bean id="accountService" class="org.example.service.AccountService">
      <property name="name" value="哈哈哈"></property>
        <property name="age" value="11"></property>
        <property name="birthdy" ref="timeObject"></property>
    </bean>


</beans>

集合数据注入:

        1.创建一个带有集合的bean

public class AccountService {
    private String[] strs;
    private List<String> list;
    private Set<String> set;
    private Map<String, String> map;
    private Properties properties;

    public String[] getStrs() {
        return strs;
    }
    public void setStrs(String[] strs) {
        this.strs = strs;
    }
    public Map<String, String> getMap() {
        return map;
    }
    public void setMap(Map<String, String> map) {
        this.map = map;
    }
    public List<String> getList() {
        return list;
    }
    public void setList(List<String> list) {
        this.list = list;
    }
    public Set<String> getSet() {
        return set;
    }
    public void setSet(Set<String> set) {
        this.set = set;
    }
    public Properties getProperties() {
        return properties;
    }
    public void setProperties(Properties properties) {
        this.properties = properties;
    }
    public void run() {
        System.out.println(strs.toString()+"\n" + list.toString()+"\n"+set.toString() + "\n"+map.toString()+"\n"+properties.toString());
    }
}

2.给集合赋值配置

        结构相同的标签,标签可以互换

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

    <bean id="accountService" class="org.example.service.AccountService">
        <!--数组赋值-->
        <property name="strs">
            <array>
                <value>值1</value>
                <value>值2</value>
            </array>
        </property>
        <!-- List 赋值-->
        <property name="list">
            <list>
                <value>值1</value>
                <value>值2</value>
            </list>
        </property>
        <!-- set赋值-->
        <property name="set">
            <set>
                <value>值1</value>
                <value>值2</value>
            </set>
        </property>

        <!-- Map 赋值-->
        <property name="map">
            <map>
                <entry key="map1" value="值1"></entry>
                <entry key="map2" value="值2"></entry>
            </map>
        </property>
        <!-- Properties 赋值-->
        <property name="properties">
            <props>
                <prop key="p1">值1</prop>
                <prop key="p2">值2</prop>
            </props>
        </property>

    </bean>


</beans>

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值