• Spring IoC 入门学习笔记


    Spring IoC基础

    IoC控制反转
    • loC控制反转,全称Inverse of Control,是一种设计理念
      由代理人来创建与管理对象,消费者通过代理人来获取对象
      loC的目的是降低对象之间直接耦合
      加入loC容器将对象统一管理,让对象关联变为弱耦合
    DI依赖注入
    • loC是设计理念,是现代程序设计遵循的标准,是宏观目标
      DI(Dependency Injection)是具体技术实现,是微观实现
      DI在Java中利用反射技术实现对象注入(Injection)
    Spring简介
    • Spring框架是企业开发复杂性的一站式解决方案
      Spring框架的核心是loC容器与AOP面向切面编程
      Spring loC负责创建与管理系统对象,并在此基础上扩展功能
    Bean的三种配置方式
    • 基于XML配置Bean
      applicationContext.xml
    
    <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
            https://www.springframework.org/schema/beans/spring-beans.xsd">
    
    
        <bean id="sweetApple" class="com.imooc.spring.ioc.entity.Apple">
            <property name="title" value="红富士">property>
            <property name="origin" value="欧洲">property>
            <property name="color" value="红色">property>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    XML方式创建IoC容器

     // 创建spring Ioc容器,并根据配置文件在容器中实例化对象
            ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    
    • 1
    • 2
    • 利用构造方法参数名实例化
    <bean id="sweetApple" class="com.imooc.spring.ioc.entity.Apple">
            
            <constructor-arg name="title" value="红富士"/>
            <constructor-arg name="origin" value="欧洲"/>
            <constructor-arg name="color" value="红色"/>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 利用构造方参数位置实例化
    <bean id="sweetApple" class="com.imooc.spring.ioc.entity.Apple">
            <constructor-arg index="0" value="红富士"/>
            <constructor-arg index="1" value="欧洲"/>
            <constructor-arg index="2" value="红色"/>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 利用静态工厂的静态方法实例化
    /**
     * 静态工厂通过静态方法创建对象,隐藏创建对象的细节
     */
    public class AppleStaticFactory {
        public static Apple createSweetApple(){
            //logger.info("")
            Apple apple = new Apple();
            apple.setTitle("红富士");
            apple.setOrigin("欧洲");
            apple.setColor("红色");
            return apple;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    
        <bean id="apple4" class="com.imooc.spring.ioc.factory.AppleStaticFactory"
              factory-method="createSweetApple"/>
    
    • 1
    • 2
    • 3
    • 利用工厂实例方法创建对象
    **
     * 工厂实例方法创建对象是指IoC容器对工厂类进行实例化并调用对应的实例方法创建对象的过程
     */
    public class AppleFactoryInstance {
        public Apple createSweetApple(){
            Apple apple = new Apple();
            apple.setTitle("红富士");
            apple.setOrigin("欧洲");
            apple.setColor("红色");
            return apple;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    
        <bean id="factoryInstance" class="com.imooc.spring.ioc.factory.AppleFactoryInstance"/>
        <bean id="apple5" factory-bean="factoryInstance" factory-method="createSweetApple"/>
    
    • 1
    • 2
    • 3
    • 从IoC容器中获取Bean
    // 初始化spring Ioc容器,并根据配置文件在容器中实例化对象
            ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
            Apple sweetApple = context.getBean("sweetApple", Apple.class);
            // 单参数方法获得Bean
            Apple sweetApple1 = (Apple) context.getBean("sweetApple");
            System.out.println(sweetApple.getTitle());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • bean标签中id与name属性相同点
      bean id与name都是设置对象在loC容器中唯一标识
      两者在同一个配置文件中都不允许出现重复
      两者允许在多个配置文件中出现重复,新对象覆盖旧对象
    • bean标签中id与name属性不同点
      id要求更为严格,一次只能定义一个对象标识(推荐)
      name更为宽松,—次允许定义多个对象标识
      tips: id与name的命名要求有意义,按驼峰命名书写
    • 在IoC容器初始化时加载多个配置文件
     		String[] configLocations = new String[]{"classpath:applicationContext.xml", "classpath:applicationContext-1.xml"};
           	ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
    
    • 1
    • 2

    注:没有id与name的bean默认使用类名全称作为bean标识,即class属性的值。

    • 路径表达式
      classpath: 指向了target目录下的classes文件夹。
      classpath:config.xml: 扫描classpath根路径(不包含jar)的config.xml
      classpath:com/imooc/config.xml: 扫描classpath下(不包含jar)com.imooc包中的config.xml
      classpath*:com/imooc/config.xml: 扫描classpath下(包含jar)com.imooc包中的
      config.xml
      classpath:config-*.xml: 扫描classpath根路径下所有以config-开头的XML文件
      classpath:com/**/config.xml: 扫描com包下(包含任何子包)的config.xml
      file:c:/config.xml: 扫描c盘根路径config.xml
    • 对象依赖注入
      依赖注入是指运行时将容器内对象利用反射赋给其他对象的操作
      基于setter方法注入对象
      基于构造方法注入对象

    使用stter方法注入对象有两种情况:

    1. 利用setter实现静态数值注入
    <bean id="sweetApple" class="com.imooc.spring.ioc.entity.Apple">
    <! -- Ioc容器自动利用反射机制运行时调用setXXX方法为属性赋值-->
    <property name="title" value="红富士"/>
    <property name="color" value="红色"/>
    <property name="origin" value="欧洲"/>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    // Ioc 的value属性可以自动调用Apple.java类中的set方法,将"红富士"赋值给了title属性,所以在getTitle时可以直接得到title的值。
    Apple sweetApple = context.getBean ( s: "sweetApple"Apple.class);
    system.out.println (sweetApple.getTitle ( ) ) ;
    // 输出是红富士
    
    • 1
    • 2
    • 3
    • 4
    1. 利用setter实现对象注入
    <bean id="lily" class="com. imooe.spring.ioc.entity.Child">
    <property name="nane" value="莉莉" />
     
    <property name="apple" ref="sweetApple" />
    bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 注入集合对象
      注入List
    
    <bean id="..." class="...">
    <property name= "someList" >
    <list>
    <value>具体值value>
    <ref bean="beanld">ref>
    list>
    property>
    bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    注入Set

    
    <bean id="..." class="...">
    <property name="someSet" >
    <set>
    <value>具体值value>
    <ref bean="beanld">ref>
    set>
    property>bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    注入Map

    
    <bean id="..." class="..." >
    <property name="someMap">
    <map>
    <entry key="k1" value="v1">entry>
    <entry key="k2" value-ref="beanld" >entry >
    
    <entry key="dev-88173">
    <bean class="com.imooc.spring.ioc.entity.Computer">
    <constructor-arg name="brand" value="联想"/>
    <constructor-arg name="type" value="笔记本"/><constructor-arg name="sn" value="1280258012"/><constructor-arg name="price" value="5060" />
    bean>
    entry>
    map>
    property>
    bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    注入Properties

    
    <bean id="..." class="...">
    <property name= "someProperties">
    <props>
    <prop key="k1">v1prop>
    <prop key="k2" >v2prop>
    props>
    property>
    bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 查看Ioc 容器里的Bean内容
    //返回一个获取容器内所有beanId的String数组
    string[] beanNames = context.getBeanDefinitionNames();
    
    • 1
    • 2
    • bean scope 属性
      bean scope属性用于决定对象何时被创建与作用范围
      bean scope配置将影响容器内对象的数量
      默认情况下bean会在loC容器创建后自动实例化,全局唯一
    <bean id="bookDao"
    class="com.imooc.spring.ioc.bookshop.dao.BookDaoOraclelmpl"scope="prototype" />
    
    • 1
    • 2

    singleton
    单例(默认值),每一个容器有且只有唯一的实例,实例被全局共享
    prototype
    多例,每次使用时都是创建一个实例
    request
    web环境下,每一次独立请求存在唯一实例
    session
    web环境下,每一个session存在有唯一实例
    global session
    portlet的web应用的共享session中
    websocket
    每一次WebSocket连接中存在唯一实例

    • singleton 与 prototype 对比
      截图来自慕课网
      默认的singleton属性会让bean在配置文件加载的时候就初始化。
      prototype属性会让配置的bean只在被关联到或者getbean方法调用的时候才初始化
    • bean的生命周期
      截图来自慕课网
      prototype时对象创建与init-method延迟至执行业务代码阶段
      prototype时对象不再受loC容器管理,不会触发destroy-method
      延迟加载lazy-init属性可让对象创建与初始化延迟到执行代码阶段
    • 基于注解配置Bean
      摆脱繁琐的XML形式的bean与依赖注入配置
      基于"声明式"的原则,更适合轻量级的现代企业应用
      让代码可读性变得更好,研发人员拥有更好的开发体验
    • 三类注解
      组件类型注解-声明当前类的功能与职责
      自动装配注解-根据属性特征自动注入对象
      元数据注解-更细化的辅助loC容器管理对象的注解
    • 组件类型注解
      @Component: 组件注解,通用注解,被该注解描述的类将被loC容器管理并实例化
      @Controller: 语义注解,说明当前类是MVC应用中的控制器类
      @Service: 语义注解,说明当前类是Service业务服务类
      @Repository: 语义注解,说明当前类用于业务持久层,通常描述对应Dao类

    开启组件扫描

    
    <context:component-scan base-package="com.imooc">
    
    <context:exclude-filter type="regex" expression="com.imooc.exl.*" />context:component-scan>
    
    • 1
    • 2
    • 3
    • 4

    例子:

    
    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            https://www.springframework.org/schema/context/spring-context.xsd">
        
        <context:annotation-config/>
        
    
        <context:component-scan base-package="com.imooc"/>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    import org.springframework.stereotype.Repository;
    // 组件类型注解默认beanId为类名首字母小写
    // beadld = userDao
    // 设置指定的beanUd: @Repository("udao")
    
    @Repository
    public class UserDao {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 自动注解装配
      按类型装配:
      @Autowired: 按容器内对象类型动态注入属性,由Spring机构提供
      @Inject: 基于JSR-330(Dependency lnjection for Java)标准, 其他同@Autowired,但不支持required属性
      按名称装配:
      @Named: 与@Inject配合使用,JSR-330规范,按属性名自动装配属性
      @Resource: 基于JSR-250规范,优先按名称、再按类型智能匹配
    // Spring IoC容器会自动通过反射技术将属性private修饰符自动改为public,直接进行赋值
    //不再执行set方法
    @Autowired
    private UserDao udao ;
    public UserDao getUdao (){
    return udao;
    @Autowired
    //如果装配注解放在set方法上,则自动按类型
    //名称对set方法参数进行注入
    public void setUdao (UserDao udao){
    System.out.println ( "setUdao : " t udao) ;
    this.udao = udao;
    )
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    /**
    * 1.@Resource设置name属性,则按name在IoC容器中将bean注入* 2.@Resource未设置name属性
    * 2.1以属性名作为bean name在Ioc容器中匹配bean ,如有匹配则注入
    * 2.2按属性名未匹配,则按类型进行匹配,同@Autowired,需加入ePrimary解决类型冲突*使用建议:在使用@Resource对象时推荐设置name或保证属性名与bean名称一致
    **/
    
    // @Resource (name = "useroracleDao")
    @Resource
    private IUserDao userOracleDao;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 元数据注解
      @Primary: 按类型装配时出现多个相同类型对象,拥有此注解对象优先被注入
      @PostConstruct: 描述方法,相当于XML中init-method配置的注解版本
      @PreDestroy: 描述方法,相当于XML中destroy-method配置的注解版本
      @Scope: 设置对象的scope属性
      @Value: 为属性注入静态数据
    • 基于Java Config代码配置Bean
      完全摆脱XML的束缚,使用独立Java类管理对象与依赖
      注解配置相对分散,利用Java Config可对配置集中管理
      可以在编译时进行依赖检查,不容易出错

    Java Config核心注解
    @Configuration: 描述类,说明当前类是Java Config配置类,完全替代XML文件
    @Bean: 描述方法,方法返回对象将被loC容器管理,beanld默认为方法名
    @lmportResource: 描述类,加载静态文件,可使用@Value注解获取
    ComponentScan: 描述类,同XML的标签

    // 配置类的代码
    @Configuration
    //当前类是一个配置类,用于替代applicationContext.xml
    public class Config {
    @Bean //Java Config利用方法创建对象,将方法返回对象放入容器, beanId=方法名
    public UserDao userDao(){
    UserDao userDao = new UserDao();
    return userDao;
    }
    @Bean
    public Userservice userservice() {
    UserService userService = new UserService();return userService;
    }
    @Bean
    public UserController userController() {
    UserController userController = new UserController() ;return userController;
    }
    }
    
    // 加载配置类的代码
    //基于Java Config配置ioc容器的初始化
    ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • Spring Test 测试模块
      Spring Test是Spring中用于测试的模块
      Spring Test对JUnit单元测试框架有良好的整合
      通过Spring Test可在JUnit在单元测试时自动初始化loC容器

    Spring 与 JUnit4 整合
    Maven工程依赖spring-test
    利用@RunWith与@ContextConfiguration描述测试用例类
    测试用例类从容器获取对象完成测试用例的执行

    需要的依赖

    <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-testartifactId>
                <version>5.2.6.RELEASEversion>
            dependency>
    
            <dependency>
                <groupId>junitgroupId>
                <artifactId>junitartifactId>
                <version>4.12version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    例子测试代码

    在这里插入代码片// 将Junit4的执行权交由spring Test,在测试用例执行前自动初始化IoC容器
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = {"classpath:applicationContext.xml"})
    public class SpringTestor {
    
        @Resource
        private UserService userService;
    
        @Test
        public  void testUserService(){
            userService.createUser();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    轻量云服务器租用好在哪
    MySQL 如何添加索引
    Shell-01Shell初相识
    [DeepLearning] 线性回归的实现Pytorch
    nltk报错punkt 缺失 Error Loading Error11004
    学习Autodock分子对接
    【Mybatis】动态sql
    Clickhouse基准测试实践
    Flowable 已经执行完毕的流程去哪找?
    14:00面试,14:06就出来了,问的问题有点变态。。。
  • 原文地址:https://blog.csdn.net/zysp158/article/details/126559766