IOC理论

IOC的原型

程序员不再管理对象的创建,更专注于业务的实现(会大大降低系统的耦合性)

一个好的程序秉承着高内聚低耦合的思想

IOC的本质(对象由Spring来创建、管理、装配)

IOC是一种设计思想,DI(依赖注入)只是实现IOC的一种方法
IOC是一种编程思想,由主动编程变为被动接收

IOC的实现方法

IOC是Spring框架的核心内容,有多种方式来实现:

  • 使用xml配置
  • 使用注解
  • 新版本的Spring也可以零配置实现IOC
    Spring容器在初始化时现读取配置文件,根据配置文件或元数据创建于组织对象存入容器中,程序使用时再从IOC容器中取出需要的对象

控制反转

控制(由Spring来创建)反转(程序本身不再创建对象,而是被动的接受对象)是一种描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IOC容器,其实现方法是依赖注入(DI)(依赖注入:利用set来实现注入)

Spring官网

https://docs.spring.io/spring-framework/reference/core/beans/basics.html

代码理解

User.java

package com.dao;

public class Users {
    private String str;

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }

    @Override
    public String toString() {
        return "Users{" +
                "str='" + str + '\'' +
                '}';
    }
}

applicationContext.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
		https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--使用Spring来创建对象,在Spring中这些都称为bean-->
    <bean id="users" class="com.dao.Users">
        <property name="str" value="Spring"/>
    </bean>

</beans>

test.java

import com.dao.Users;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.HashMap;

public class MyText {


    @Test
    public void mytext() {
//        获取Spring的上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext ("applicationContext.xml");
        Users users = (Users) context.getBean ("users");
        System.out.println (users.toString ());

    }

}

运行结果
在这里插入图片描述

IOC创建对象的方式

  1. 使用无参构造创建对象。默认
  2. 使用有参构造创建对象

2.1下标赋值

    <bean id="users" class="com.dao.Users">
        <!--<property name="str" value="Spring"/>-->
        <constructor-arg index="0" value="我是有参构造注入的下标赋值"/>
    </bean>

2.2类型赋值

    <!--使用Spring来创建对象,在Spring中这些都称为bean-->
    <bean id="users" class="com.dao.Users">
        <constructor-arg type="java.lang.String" value="我是类型注入"/>
    </bean>

2.3直接通过参数名

  <!--使用Spring来创建对象,在Spring中这些都称为bean-->
    <bean id="users" class="com.dao.Users">
        <constructor-arg name="str" value="直接通过参数名"/>
    </bean>

Spring配置

别名(alias,可以通过别名获取到该对象)

    <alias name="users" alias="users2"/>

    <!--id:Bean的唯一标识符,也就是相当于我们学的对象名 ,classBean对象所对应的全限定名:包名+类名  name:别名-->
    <bean id="users" class="com.dao.Users" name="users3">
        <constructor-arg name="str" value="直接通过参数名"/>
    </bean>

import

一般用于团队使用,将多个配置文件导入合并为一个

DI依赖注入

Set注入(重点)

  • 依赖注入:Set注入
    • 依赖:Bean对象的创建依赖于容器
    • 注入:Bean对象中的所有属性,由容器来注入

复杂类型

public class Address {
    private String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

实际对象

public class Student {
    private String name;
    private Address address;
    private String[] books;
    private List<String> hobby;
    private Map<String, String> card;
    private String wife;
    private Properties info;
    }

applicationContext.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
		https://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="address" class="com.pojo.Address">
        <property name="address" value="我是地址"/>
    </bean>
    <bean id="student" class="com.pojo.Student">
        <!--第一种,普通值(value)注入-->
        <property name="name" value="测试"/>
        <!--第二种,Bean注入-->
        <property name="address" ref="address"/>
        <!--数组注入-->
        <property name="books">
            <array>
                <value>我是数组1</value>
                <value>我是数组2</value>
                <value>我是数组3</value>
            </array>
        </property>
        <!--list注入-->
        <property name="hobby">
            <list>
                <value>我是list注入1</value>
                <value>我是list注入2</value>
                <value>我是list注入3</value>
            </list>
        </property>
        <!--map注入-->
        <property name="card">
            <map>
                <entry key="我是map1的key" value="我是map1"/>
                <entry key="我是map2的key" value="我是map2"/>
                <entry key="我是map3的key" value="我是map3"/>
            </map>
        </property>
        <!--空值注入-->
        <property name="wife">
            <null/>
        </property>
        <!--Properties注入-->
        <property name="info">
            <props>
                <prop key="我是Properties1的key">我是Properties1</prop>
                <prop key="我是Properties2的key">我是Properties2</prop>
                <prop key="我是Properties3的key">我是Properties3</prop>
            </props>
        </property>
    </bean>
</beans>

MyTest.java(测试类)

import com.pojo.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {

    @Test
    public void cs() {

        ApplicationContext context = new ClassPathXmlApplicationContext ("beans.xml");
        Student student = (Student) context.getBean ("student");
        System.out.println (student.toString ());

    }
}


官网参考这里是引用

构造器注入

其他注入

p注入(快捷的set注入)

  • 导入p命名空间
   xmlns:p="http://www.springframework.org/schema/p"
  • 实现
    userBeans.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"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
		https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--p命名空间注入,可以直接注入属性的值:相当于property-->

    <bean id="user" class="com.pojo.User" p:name="我是p命名注入" p:age="20"/>

</beans>

测试


    @Test
    public void cs2() {
        ApplicationContext context = new ClassPathXmlApplicationContext ("userBwans.xml");
        User user = (User) context.getBean ("user");
        System.out.println (user.toString ());
    }

c注入(快捷的构造器注入)

导入c命名空间

	xmlns:c="http://www.springframework.org/schema/c"

实现
userBeas.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"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
		https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--p命名空间注入,可以直接注入属性的值:相当于property-->
    <bean id="user" class="com.pojo.User" c:name="我是c注入" c:age="20"/>

</beans>

cs.java


    @Test
    public void cs2() {
        ApplicationContext context = new ClassPathXmlApplicationContext ("userBwans.xml");
        User user = (User) context.getBean ("user");
        System.out.println (user.toString ());
    }

Bean scopes(Bean 作用域)

官方解释导航
在这里插入图片描述

重点掌握
在这里插入图片描述

  • 单例模式(Spring模式机制)
`<bean id="user" class="com.pojo.User" c:name="我是c注入" c:age="20" scope="singleton"/>
  • 原型模式(每次从容器中get时都会产生新的对象)
<bean id="user" class="com.pojo.User" c:name="我是c注入" c:age="20" scope="prototype"/>
  • 其余的request、session、application,只能在Web开放中使用

Bean的自动装配

  • 自动装配是Spring满足Bean依赖的一种方式
  • Spring会在上下文中自动寻找,并自动给Bean装配属性

在Sprin中又三种自动装配的方式:

  1. 在xml中显示的配置
  2. 在Java中显示的配置
  3. 隐式的自动装配

测试代码搭建
Dog.java

package com.pojo;

public class Dog {

    public void shut() {
        System.out.println ("汪汪汪~");
    }
}

Cat.java

package com.pojo;

public class Cat {

    public void shut() {
        System.out.println ("喵喵喵~");
    }
}

People.java

package com.pojo;

public class People {

    private String name;
    private Dog dog;
    private Cat cat;

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                ", dog=" + dog +
                ", cat=" + cat +
                '}';
    }

    public void setName(String name) {
        this.name = name;
    }

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }
}

myTest.java

import com.pojo.People;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {


    @Test
    public void test1() {
        ApplicationContext context = new ClassPathXmlApplicationContext ("beans.xml");
        People people = context.getBean ("people", People.class);
        people.getCat ().shut ();
        people.getDog ().shut ();
    }
}

  • byName自动装配
<?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
		https://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="dog" class="com.pojo.Dog"/>
    <bean id="cat" class="com.pojo.Cat"/>
    <!--byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanid-->
    <bean id="people" class="com.pojo.People" autowire="byName">
        <property name="dog" ref="dog"/>
        <property name="cat" ref="cat"/>
        <property name="name" value="测试"/>
    </bean>

</beans>
  • byType自动装配
<?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
		https://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="dog" class="com.pojo.Dog"/>
    <bean id="cat" class="com.pojo.Cat"/>
    <!--byType:会自动在容器上下文中查找,和自己对象属性类型相同的beanid-->
    <bean id="people" class="com.pojo.People" autowire="byType">
        <property name="dog" ref="dog"/>
        <property name="cat" ref="cat"/>
        <property name="name" value="测试"/>
    </bean>

</beans>

在这里插入图片描述

小结:
byname的时候,需要保证所有的bean的id是唯一,并且这个bean需要和自动注入的属性的Set方法的值是一致的
bytype的时候,需要保证所有的bean的class是唯一的,并且这个bean需要和自动注入的属性的类型一致!

注解实现自动装配

使用注解的要求

  1. 导入约束
xmlns:context="http://www.springframework.org/schema/context"
  1. 配置注解支持
<?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: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/>

</beans>

@Autowired

直接在属性上使用即可,也可以在Set方式上使用!
使用Autowired我们可以不用编写Set方法了,前提自动装配的属性在IOC(Spring)容器中存在,且符合名字byname

科普:
@Nullable:字段标记了这个注解,说明这个字段可以为null
@Autowired (required=false):说明这个对象可以为空,否则则不允许为空
public @interface Autowired {
boolean required() default true;
}
测试代码:
public class People {
private String name;
@Autowired(required = false)
private Dog dog;
@Autowired
private Cat cat;
}
如果 @Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,我们可以通过 @Qualifier(value = "XXX"取配置@Autowired的使用,指定一个唯一的bean对象注入

Resource注解(功能跟Autowired差不多)

    @Resource(name = "cat")
    private Cat cat;

小结:
@Resource和 @Autowired的区别
都是用来自动装配的,都可以放在属性字段上
@Autowired通过byType的方式实现,而且必须要求这个对象存在(常用)
@Resource默认通过byname的方式实现,如果找不到名字,则通过byType实现,如果两个都找不到的情况下,就报错(常用)
执行顺序不同:@Resource默认通过byname实现, @Autowired通过byType的方式实现。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值