Spring--IOC


以下是本篇文章正文内容,下面案例可供参考

IOC

一、概念

  • 控制反转,把对象创建和对象之间的调用过程,交给Spring进行管理
  • 使用IOC目的:为了降低耦合度
  • 做入门案例就是IOC实现

二、原理

  • xml解析

  • 工厂模式

    • 在这里插入图片描述
  • 反射

    class UserFactory{
    	public static UserDao getDao(){
    		String classValue = class属性值;//xml解析
    		Class class = Class.forName(classValue);//通过反射创建对象
    		return (UserDao)class.newInstance();
    	}
    }
    

三、IOC(接口)

  1. IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
  2. Spring提供IOC容器实现两种方式:(2个接口)
    1. 功能:加载配置文件,创建对象
    2. BeanFactory:
      1. IOC容器基本实现,是Spring内部的使用接口,不提供开发人员进行使用
    3. ApplicationContext
      1. BeanFactory接口的子接口,提供更加强大的功能,一般面向开发人员使用
    4. 2个接口的区别:
      1. BeanFactory:加载配置文件时不会创建对象,在获取/使用对象才创建对象
      2. ApplicationContext:加载配置文件时就创建对象
  3. ApplicationContext接口实现类
    1. FileSystemXmlApplicationContext:绝对路径
    2. ClassPathXmlApplicationContext:相对路径

四、IOC操作Bean管理

4.1 什么是Bean管理

  • Bean管理指的是两个操作
    • Spring创建对象
    • Spring注入属性
  • Bean管理操作有两种方式
    • 基于xml配置文件方式实现
    • 基于注解方式实现

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

4.2.1 基于xml方式创建对象
  1. <!--    配置User对象创建-->
    <bean id="user" class="cn.future.spring5.User"></bean>
    
    1. 在spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建
    2. 在bean标签有很多属性,
      1. id:唯一标识
      2. class:类全路径(包类路径)
    3. 创建类时,默认也是执行无参数构造方法完成对象创建
4.2.2 基于xml方式中注入属性
第一种方式:set注入

DI:依赖注入,就是注入属性

//类的编写
package cn.future.spring5;

public class Book {
    //创建属性
    private String bName;
    private String bAuthor;

    //创建属性对应的set方法
    public void setbName(String bName) {
        this.bName = bName;
    }

    public void setbAuthor(String bAuthor) {
        this.bAuthor = bAuthor;
    }

    public static void main(String[] args) {
        Book book = new Book();
        book.setbName("hello");
    }
}

<!--    xml编写   -->
<!--    set方法注入属性-->
    <bean id="book" class="cn.future.spring5.Book" >
        <!--    使用property完成属性注入
            name:类的属性名称
            value:向属性注入的值
            -->
        <property name="bName" value="易筋经"></property>
        <property name="bAuthor" value="达摩"></property>
    </bean>
//测试类
public class BookSpring5 {

    @Test
    public void testBook1(){
        //1.加载spring配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        //2.获取配置创建的对象
        Book book = context.getBean("book",Book.class);
        System.out.println(book);
        book.testDemo();
    }


}
第二种方法:有参构造注入
  1. 创建类,定义属性,创建有参构造方法

    package cn.future.spring5;
    
    public class Order {
        private String oname;
        private String address;
    
        //有参数构造
        public Order(String oname, String address) {
            this.oname = oname;
            this.address = address;
        }
    
        public void show(){
            System.out.println(oname+address);
        }
    }
    
    
        <bean id="order" class="cn.future.spring5.Order">
            <constructor-arg name="address" value="电脑"></constructor-arg>
            <constructor-arg name="oname" value="戴尔"></constructor-arg>
        </bean>
    
    public class testSpring5 {
        @Test
        public void testAdd(){
            //1.加载spring配置文件
            ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
            //2.获取配置创建的对象
            User user = context.getBean("user", User.class);
            System.out.println(user);
            user.add();
        }
    }
    
4.2.3 xml注入其他类型属性

字面量

  • null值
  • 属性值包含特殊符号
4.2.4 注入属性-外部bean
  1. 创建2个类service类和dao类
  2. 在service调用dao里面的方法
4.2.5 注入属性-内部bean和级别赋值
4.2.6 注入集合类型属性
不提取方法
<?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="stu" class="cn.future.spring5.Stu">
        <!--   数组类型     -->
        <property name="strs">
            <array>
                <value>java</value>
                <value>python</value>
                <value>mysql</value>
            </array>
        </property>

        <!--   list类型注入     -->
        <property name="list">
            <list>
                <value>张三</value>
                <value>李四</value>
            </list>
        </property>

        <!--    map集合    -->
        <property name="map">
            <map>
                <entry key="Java" value="java"></entry>
                <entry key = "Pythom" value="python"></entry>
            </map>
        </property>

        <!--        set集合-->
        <property name="sets">
            <set>
                <value>hello</value>
                <value>java</value>
            </set>
        </property>

        <!--        注入list 对象集合-->
        <property name="bookList">
            <list>
                <ref bean="book1"></ref>
                <ref bean="book2"></ref>
            </list>
        </property>
    </bean>

    <bean id="book1" class="cn.future.spring5.Book">
        <property name="bAuthor" value="哈姆雷特"></property>
        <property name="bName" value="猪头"></property>
    </bean>

    <bean id="book2" class="cn.future.spring5.Book">
        <property name="bAuthor" value="哈姆雷特"></property>
        <property name="bName" value="猪头"></property>
    </bean>
</beans>
提取方法
<!--    提取list集合类型属性注入  -->
    <bean id="Stu" class="cn.future.spring5.Stu">
        <property name="bookList">
            <ref bean="book"></ref>
        </property>
        <property name="map">
            <ref bean="map"></ref>
        </property>
        <property name="sets">
            <ref bean="set"></ref>
        </property>
        <property name="list">
            <ref bean="list"></ref>
        </property>
    </bean>
    
    <!--    book list 抽取-->
    <util:list id="book">
        <ref bean="book1"></ref>
        <ref bean="book2"></ref>
    </util:list>
    
    <!--  map 抽取  -->
    <util:map id="map">
        <entry key="Java" value="java"></entry>
        <entry key="PytHon" value="python"></entry>
    </util:map>

    <!-- set抽取   -->
    <util:set id="set">
        <value>宇猪头</value>
        <value>孙猪头</value>
    </util:set>

    <!-- list抽取   -->
    <util:list id="list">
        <value>你好</value>
        <value>笨蛋</value>
    </util:list>

    <bean id="book1" class="cn.future.spring5.Book">
        <property name="bName" value=""></property>
        <property name="bAuthor" value=""></property>
    </bean>
    <bean id="book2" class="cn.future.spring5.Book">
        <property name="bName" value=""></property>
        <property name="bAuthor" value=""></property>
    </bean>

4.3 Bean的种类

  • 普通bean:在配置文件中定义bean类型就是返回类型
  • 工厂bean:在配置文件中定义哦bean类型可以和返回类型不一样
    • 第一步 创建类,让这个类作为工厂bean,实现接口FactoryBean
    • 第二步 实现接口里面的方法,在实现的方法中定义返回的bean类型

4.4 Bean的作用域

  • 在Spring里面,设置创建bean实例是单实例还是多实例(单实例:创建多次,是同一个对象)
  • 在spring里面,设置创建对象为单实例对象
  • 如何设置单实例还是多实例
    • scope用于设置单实例还是多实例
    • 默认值singleton,表示单实例
    • prototype,表示是多实例
    • 两者区别:
      • singleton表示单实例,加载配置文件时会创建单实例对象
      • prototype表示多实例,在调用getBean()时创建多实例对象

4.5 Bean的生命周期

  • 通过构造器创建bean实例(无参数构造)
  • 为bean的属性设置值和对其他bean的引用(调用set方法)
  • 把bean实例传递bean后置处理器的方法
  • 调用bean的初始化的方法(需要进行配置)
  • 把bean实例传递bean后置处理器的方法
  • bean可以使用了(对象获取到了)
  • 当容器关闭时候,调用bean的销毁的方法(需要进行配置销毁的方法)

后置处理器

  • 定义一个类,实现接口BeanPostProcessor

xml

<bean id = "orders" class="cn.future.bean.Orders" init-method="initMehod">
    <property name="oname" value="java"></property>
</bean>

<!--    配置后置处理器     -->
    <bean id="MyBeanPost" class="cn.future.bean.MyBeanPost"></bean>

后置处理器

public class MyBeanPost implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化之前执行的方法");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化之后执行的方法");
        return bean;
    }
}

4.6 xml自动装配

  • 什么是自动装配

    • 根据指定装配规则(属性名称或者属性类型),spring自动将匹配的属性值进行注入
  •     <!--     自动装配
                 bean标签属性autowire,配置自动装配
                 autowire有2个常用值
                 1) byName:根据属性名注入,注入值bean的id值和类属性名必须一样
                 2)byType:根据类型注入,相同类型的bean不能定义多个
        -->
        <bean id="Emp" class="cn.future.auto.Emp" autowire="byType">
            <!--        手动装配-->
            <!--        <property name="dept" ref="Dept"></property>-->
        </bean>
        <bean id="dept" class="cn.future.auto.Dept"></bean>
    

4.7 外部属性文件

  • 直接配置数据库信息
    • 配置德鲁伊连接池
    • 引入德鲁伊连接池依赖jar包
  • 引入外部属性文件配置数据库连接池

4.8 基于注解方式

  • 什么是注释

    • 注解是代码特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值)
    • 使用注解,注解作用在类上面,方法上面,属性上面
    • 使用注解目的:简化xml配置
  • Bean管理中创建对象的注解

    • @Component
    • @Service
    • @Controller
    • @Repository
  • 基于注解方式实现对象的创建

    • 第一步:引入依赖 spring-aop-5.2.6.RELEASE.jar
    • 第二步:开启组件扫描
    • 第三步:创建类,在类上面添加创建注解
  • 基于注解方式实现属性注入

    • @Autowired:根据属性类型进行自动装配
    • @Qualifier:根据属性名称进行注入
    • @Resourse:可以根据类型注入,可以根据名称注入
    • @Value:注入普通类型属性
  • 完全注解开发

    • //创建配置类,替代xml配置文件
      @Configuration
      @ComponentScan(basePackages = {"..."})
      public class SpringConfig{
          
      }
      

五、@Resource和@Autowired

  • 都是用来实现自动装配的,都可以放在属性字段上
  • @Autowired通过ByType实现自动装配,且要求这个对象必须存在
  • @Resource通过ByName实现自动装配,如果找不到名字,通过ByType实现,如果两个都找不到的情况,就报错
  • 执行顺序不同,@Autowired通过ByType的方式实现,@Resource通过ByName实现自动装配

六、使用JavaConfig开发

​ 配置类

 /**
  * @Configuration代表的是一个配置类,就和beans.xml一样
  */
 @Configuration
 @ComponentScan("com.futureport")
 public class Config {
 
     /**
      * 注册一个Bean
      * 这个方法的名字,就相当于bean标签的id属性
      * 这个方法的返回值,就相当于bean标签中的class属性
      * @return
     */
     @Bean
     public User getUser(){         
     	return new User();//返回到要注入bean的对象
     }
 }

​ 实体类

 @Component
 public class User {
  @Value("hello")
  public String name;
 }
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Anonymous&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值