Spring之IOC(xml配置)

1.简介

IOC( Inversion of Control ),控制反转,也叫依赖注入DI(dependency injection),是Spring框架Core模块提供的核心功能。

“控制反转”:对象A运行需要对象B,由主动创建变为IOC容器注入,这便是控制反转。

“依赖注入”:获得依赖对象的过程被反转了,获取依赖对象的过程由自身创建变为由IOC容器注入,这便是依赖注入。

2.快速入门

  1. 引入依赖

    <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.1</version>
    </dependency>
    
  2. 新建一个Person类

    public class Person {
    
        private String name;
    
        private int age;
    
        public void sayHello(){
            System.out.println("hello!");
        }
    
        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;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    
  3. 创建bean1.xml

    <?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="person" class="com.apple.spring.bean.Person"></bean>
    </beans>
    
  4. 使用容器创建对象

    ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
    Person person = context.getBean("person", Person.class);
    person.sayHello();	  //hello!
    

3.IOC容器两种实现方式

3.1 BeanFactory

IOC容器基本实现,是Spring内部的使用接口,不提供开发人员进行使用

  • 加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象

3.2 ApplicationContext

BeanFactory接口的子接口,提供更多更强大的功能,一般由开发人员进行使用

  • 加载配置文件时候就会把在配置文件对象进行创建
  • 有两个实现类接口:
    • ClassPathXmlApplicationContext,加载类文件基于src目录下的类路径
    • FileSystemXmlApplicationContext,加载类文件基于硬盘路径,C://…

4.Bean的常用属性配置

4.1 id

bean的唯一标识,同一个Spring容器中不允许重复

4.2 class

全类名,用于反射创建对象

4.3 scope

scope主要有两个值: singleton和prototype。

如果设置为singleton,则一个容器中只会有这个一个bean对象。默认容器创建的时候就会创建该对象.

如果设置为prototype,则一个容器中会有多个该bean对象。每次调用getBean方法获取时都会创建一个新对象

5.DI依赖注入

5.1 set方法注入

在要注入属性的bean标签中进行配置。前提是该类有提供属性对应的set方法

<bean id="person" class="com.apple.spring.bean.Person">
	<property name="name" value="杰克"></property>
    <property name="age" value="18"></property>
</bean>

创建容器查看注入的属性

ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
Person person = context.getBean("person", Person.class);
System.out.println(person); //Person{name='杰克', age=18}

如果Person有个Cat属性

public class Cat {
    
    private String type;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
}

bean1.xml配置,ref属性用于给引用类型的属性设置值,和Spring容器中bean的id相对应

<bean id="person" class="com.apple.spring.bean.Person">
    <property name="name" value="杰克"></property>
    <property name="age" value="18"></property>
    <property name="cat" ref="Cat"></property>
</bean>

<bean id="Cat" class="com.apple.spring.bean.Cat">
    <property name="type" value="奶牛猫"/>
</bean>

测试结果:Person{name=‘杰克’, age=18, cat=Cat{type=‘奶牛猫’}}

5.2 有参构造注入

在要注入属性的bean标签中进行配置。前提是该类有提供对应的有参构造

bean1.xml文件配置

<bean id="person" class="com.apple.spring.bean.Person">
    <constructor-arg name="name" value="肉丝"></constructor-arg>
    <constructor-arg name="age" value="18"></constructor-arg>
    <constructor-arg name="cat" ref="Cat"></constructor-arg>
</bean>

<bean id="Cat" class="com.apple.spring.bean.Cat">
    <property name="type" value="奶牛猫"/>
</bean>

测试结果:Person{name=‘肉丝’, age=18, cat=Cat{type=‘奶牛猫’}}

5.3 复杂类型属性注入

Person类增加了这些属性

public class Person {

    private String name;

    private int age;

    private Cat cat;

    private List<String> list;

    private List<Cat> cats;

    private Set<String> set;

    private Map<String,Cat> map;

    private int[] arr;

    private Properties properties;
    ...//省略了get、set、toString方法
}

bean1.xml配置

<bean id="person" class="com.apple.spring.bean.Person">
        <property name="name" value="Mary"></property>
        <property name="age" value="10"></property>
        <property name="cat" ref="Cat"></property>
        <property name="list">
            <list>
                <value>小智</value>
                <value>皮卡丘</value>
            </list>
        </property>
        <property name="cats">
            <list>
                <ref bean="Cat"></ref>
            </list>
        </property>
        <property name="set">
            <set>
                <value>小光</value>
                <value>波加曼</value>
            </set>
        </property>
        <property name="map">
            <map>
                <entry key="黑猫警长" value-ref="Cat"></entry>
            </map>
        </property>
        <property name="arr">
            <array>
                <value>1</value>
                <value>2</value>
            </array>
        </property>
        <property name="properties">
            <props>
                <prop key="小霞">可达鸭</prop>
                <prop key="小刚">大岩蛇</prop>
            </props>
        </property>
    </bean>

    <bean id="Cat" class="com.apple.spring.bean.Cat">
        <property name="type" value="奶牛猫"/>
    </bean>

测试结果:Person{name=‘Mary’, age=10, cat=Cat{type=‘奶牛猫’}, list=[小智, 皮卡丘], cats=[Cat{type=‘奶牛猫’}], set=[小光, 波加曼], map={黑猫警长=Cat{type=‘奶牛猫’}}, arr=[1, 2], properties={小刚=大岩蛇, 小霞=可达鸭}}

6.SPEL

我们可以在配置文件中使用SPEL表达式,写法如下:

<property name="age" value="#{10}"></property>
<property name="cat" value="#{Cat}"></property>

注意: SPEL需要写到value属性中,不能写到ref属性

7.读取使用properties配置文件

7.1 创建jdbc.properties

prop.driverClass=com.mysql.jdbc.Driver
prop.url=com.mysql.jdbc.Driver
prop.userName=root
prop.password=root

7.2 引入context命名空间

<bean xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       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
                            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"/>

7.3 引入properties配置文件,进行配置

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

<!--配置连接池-->
<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>

8.引入Spring配置文件

我们可以在主的配置文件中通过import标签的resource属性,引入其它的xml配置文件

<import resource="classpath:jdbc.xml"></import>

9.bean的不常用配置

9.1 name属性

我们可以用name属性来给bean取名,一个多个都可以

<bean id="person" class="com.apple.spring.bean.Person" name="person2,person3"/>

获取的时候就可以使用这个名字来获取了

ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
Person person = (Person) context.getBean("person3");

9.2 lazy-init

可以控制bean的创建时间,如果设置为true就是在第一次获取该对象的时候才去创建。

<bean id="person" class="com.apple.spring.bean.Person" lazy-init="true"/>

9.3 init-method

可以用来设置初始化方法,设置完后容器创建完对象就会自动帮我们调用对应的方法

 <bean id="person" class="com.apple.spring.bean.Person" init-method="sayHello"/>

注意:配置的初始化方法只能是空参

9.4 destroy-method

可以用来设置销毁之前调用的方法,设置完后容器销毁对象前就会自动帮我们调用对应的方法

 <bean id="person" class="com.apple.spring.bean.Person" destroy-method="sayBye"/>

注意:配置的初始化方法也只能是空参

9.5 factory-bean和factory-method

现实中一辆汽车是由很多零件构成的,汽车工厂负责将各种零件组装起来

//Car.java
public class Car {

    //方向盘
    private SteeringWheel steeringWheel;
    //轮胎
    private Tyre tyre;
    //发动机
    private Motor motor;

    public SteeringWheel getSteeringWheel() {
        return steeringWheel;
    }

    public void setSteeringWheel(SteeringWheel steeringWheel) {
        this.steeringWheel = steeringWheel;
    }

    public Tyre getTyre() {
        return tyre;
    }

    public void setTyre(Tyre tyre) {
        this.tyre = tyre;
    }

    public Motor getMotor() {
        return motor;
    }

    public void setMotor(Motor motor) {
        this.motor = motor;
    }
}
//CarFactory.java
public class CarFactory {

    public Car getCar(){
        Car c = new Car();
        c.setMotor(new Motor());
        c.setSteeringWheel(new SteeringWheel());
        c.setTyre(new Tyre());
        return c;

    }
}

bean2.xml配置

<!--创建实例工厂-->
<bean class="com.apple.spring.factory.CarFactory" id="carFactory"></bean>
<!--使用实例工厂创建Car放入容器-->
<!--factory-bean 用来指定使用哪个工厂对象-->
<!--factory-method 用来指定使用哪个工厂方法-->
<bean factory-bean="carFactory" factory-method="getCar" id="car"></bean>

测试使用

ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
Car car = (Car) context.getBean("car");
System.out.println(car);

也可以使用静态工厂创建Car

public class CarFactory {

    public static Car getCar(){
        Car c = new Car();
        c.setMotor(new Motor());
        c.setSteeringWheel(new SteeringWheel());
        c.setTyre(new Tyre());
        return c;
    }
}
<bean class="com.apple.spring.factory.CarFactory" factory-method="getCar" id="car2"></bean>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值