Spring IOC

前言

Spring框架的介绍

1.Spring框架的概述:
  • Spring是一个开放源代码的设计层面框架,它解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。
  • Spring是于2003 年兴起的一个轻量级的Java开发框架,由Rod Johnson在其著作Expert One-On-One J2EE.Development and Design中阐述的部分理念和原型衍生而来。
  • 它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。
  • Spring的核心是控制反转(IOC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架。

2.Spring框架的优点
  • 方便解耦,简化开发,Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理,这也是IOC的作用。
  • AOP编程的支持,Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能。
  • 声明式事务的支持,只需要通过配置就可以完成对事务的管理,而无需手动编程。
  • 方便程序的测试,Spring对Junit4支持,可以通过注解方便的测试Spring程序。
  • 方便集成各种优秀框架,Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts2、Hibernate、MyBatis等)的直接支持。
  • 降低JavaEE API的使用难度,Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail等),都提供了封装,使这些API应用难度大大降低。

我们学习Spring 主要学习Spring的两大点:

1.IOC(控制权反转)

2.AOP(面向切面编程)

接下来我们就IOC,进行讨论,想要了解AOP的小伙伴们,请见小编的Spring AOP一文spring AOP-CSDN博客

什么是IOC

用一句通俗的话来讲就是把创建对象的过程交给Spring 框架进行管理

回顾一下我们以前创建对象的方法,有new 构造器()或者反射。

为什么会有IOC技术

为了降低代码的耦合度

在这里就好像一个大齿轮一样,三个紧密相连,如果其中一个损坏,那么剩下的两个很难运行

这时候我们就需要一个“”中间人”。在程序启动的时候,自动把a,b,c对象生成,并且封装在一个容器当中,需要用到时候就在类里面调用。

IOC实操

1.导入相关依赖
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.0.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.12</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>
2.编写Spring核心的配置文件

在resources目录下创建applicationContext.xml的配置文件,名称是可以任意的,但是一般都会使用默认名称。(小编写的是Application.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">
  	 <!--IOC管理bean-->
    <!--id:类的唯一标识符 class:类的全路径名-->
    <bean id="demo" class="com.qcby.service.Demo" />
</beans>

3.Spring对对象的管理

1)配置文件创建对象

test类当中:

//    传统创建对象的方法
    @Test
    public void run(){
        Demo2 demo = new Demo2();
        demo.hello();
    }

    @Test
//    Spring创建对象的方法
    public void run_spring(){
        //创建Spring工厂,加载配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("Application.xml");
        //获取bean对象
        Demo2 demo2 = (Demo2) applicationContext.getBean("demo2");
        demo2.hello();

        applicationContext.getBean("user");
    }

 demo2.Hello 调用相关方法

applicationContext.getBean("user") 获取user对象

Application.xml 文件:

<!--    id是唯一标识符,class跟的是类的全路径名,可以通过反射的方式创建对象-->
    <bean id="demo2" class="com.qcby.service.Demo2"/>
    <bean id="user" class="com.qcby.service.User"/>

先去加载xml文件,在xml文件当中加载做好的相关配置(映射扫描生成想要的对象)

2)配置文件注入属性
set方法注入属性

属性、数组、集合等的set注入

类user2:

import java.util.List;
import java.util.Map;

public class User2 {
    private int age;
    private String name;
    private Demo2 demo2;
    private String str;
    private List<String> list;
    private Map<String,String> map;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Demo2 getDemo2() {
        return demo2;
    }

    public void setDemo2(Demo2 demo2) {
        this.demo2 = demo2;
    }

    public String getStr() {
        return str;
    }

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

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public Map<String, String> getMap() {
        return map;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    @Override
    public String toString() {
        return "User2{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", demo2=" + demo2 +
                ", str='" + str + '\'' +
                ", list=" + list +
                ", map=" + map +
                '}';
    }

Application.xml:

<!--    属性注入-->
<!--    使用property完成属性注入-->
<!--    name 类里面的属性名称-->
<!--    value 向属性注入值-->
<!--    ref 对象映射-->
    <bean id="user2" class="com.qcby.service.User2">
        <property name="age" value="20"/>
        <property name="name" value="张三"/>
        <property name="demo2" ref="demo2"/>
        <property name="str" >
            <array>
                <value>张三</value>
                <value>李四</value>
                <value>王五</value>
            </array>
        </property>
        <property name="list">
            <list>
                <value>熊大</value>
                <value>熊二</value>
                <value>光头强</value>
            </list>
        </property>
        <property name="map">
            <map>
                <entry key="张三" value="法外狂徒"/>
                <entry key="星辰" value="小编本身"/>
            </map>
        </property>
    </bean>
构造器方法注入属性

Application.xml

  <bean id="demo2" class="com.qcby.service.Demo2"/>
    <bean id="user2" class="com.qcby.service.User2">
        <constructor-arg name="age" value="20"/>
        <constructor-arg name="name" value="张三"/>
        <constructor-arg name="demo2" ref="demo2"/>
        <constructor-arg name="str">
            <array>
                <value>张三</value>
                <value>李四</value>
                <value>王五</value>
            </array>
        </constructor-arg>
        <constructor-arg name="list" >
            <list>
                <value>熊大</value>
                <value>熊二</value>
            </list>
        </constructor-arg>
        <constructor-arg name="map">
            <map>
                <entry key="abc" value="de"/>
                <entry key="cba" value="ed"/>
            </map>
        </constructor-arg>
    </bean>

User2

import java.util.Arrays;
import java.util.List;
import java.util.Map;

public class User2 {
    private int age;
    private String name;
    private Demo2 demo2;
    private String[] str;
    private List<String> list;
    private Map<String,String> map;
    
    //利用构造器赋值
    public User2(int age, String name, Demo2 demo2, String[] str, List<String> list, Map<String, String> map) {
        this.age = age;
        this.name = name;
        this.demo2 = demo2;
        this.str = str;
        this.list = list;
        this.map = map;
    }

    @Override
    public String toString() {
        return "User2{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", demo2=" + demo2 +
                ", str=" + Arrays.toString(str) +
                ", list=" + list +
                ", map=" + map +
                '}';
    }

测试:

@Test
    public void run_set(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("Application.xml");
        User2 user2 = (User2) applicationContext.getBean("user2");
        System.out.println(user2.toString());
    }
3)注解方式创建对象

1.什么是注解

  • 注解是代码的特殊标记,格式:@注解名称(属性名称=属性值,属性名称=属性值...)
  • 使用注解,注解作用在类上面,方法上面,属性上面
  • 使用注解的目的:简化XML配置

 2.Spring针对Bean管理中创建对象提供的注解(都可以用来创建bean实例)

@Component 普通的类

@Controller 表现层

@Service 业务层

@Repository 持久层

可以在配置文件里面加上@Bean也可以交给spring去管理

3.用注解的功能

配置文件

<?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:aop="http://www.springframework.org/schema/aop"
       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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">


<!--    配置固定要扫描的包-->
    <context:component-scan base-package="com.qcby.service"/>

</beans>

 在需要管理的类上增加Component注解

import org.springframework.stereotype.Component;

@Component(value = "demo2")
public class Demo2 {
    public void hello(){
        System.out.println("Hello,world!");
    }
}

编写实现类

 @Test
    public void run_0(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("Application.xml");
       //ClassPathXmlApplicationContext 括号里跟的是相对路径 FileSystemXmlApplicationContext 括号里跟的是绝对路径
       Demo2 demo2 = (Demo2) applicationContext.getBean("demo2");
       demo2.hello();
    }
4)注解方式注入属性

@Value 用于注入普通类型(String,int,double等类型)

@Autowired 默认按类型进行自动装配(引用类型)

@Qualifier 不能单独使用必须和@Autowired一起使用,强制使用名称注入

@Resource Java提供的注解,也被支持。使用name属性,按名称注入

// 默认当前类名就是ID名称,首字母小写
@Component(value = "c")
// @Controller
// @Service(value = "c")
// @Repository(valu = "c")
public class Car {
    // 注解注入值,属性set方法是可以省略不写的。
    // 只有一个属性,属性的名称是value,value是可以省略不写的
    @Value("大奔2")
    private String cname;
    @Value(value = "400000")
    private Double money;
    // 也不用提供set方法
    // 按类型自动装配的注解,和id名称没有关系

    @Autowired
    // 按id的名称注入,Qualifier不能单独使用,需要Autowired一起使用。
    // @Qualifier(value = "person")
    // @Resource Java提供的注解,按名称注入对象,属性名称是name
    // @Resource(name = "person")
    private Person person;


    @Override
    public String toString() {
        return "Car{" +
                "cname='" + cname + '\'' +
                ", money=" + money +
                ", person=" + person +
                '}';
    }

}
@Controller
//@Component(value = "person")
public class Person {

    @Value("张三")
    private String pname;
    @Override
    public String toString() {
        return "Person{" +
                "pname='" + pname + '\'' +
                '}';
    }

}
@Test
public void run1(){
    // 工厂
    ApplicationContext ac = new
            ClassPathXmlApplicationContext("applicationContext.xml");
    // 获取对象
    Car car = (Car) ac.getBean("c");
    System.out.println(car);
}

IOC技术总结

ApplicationContext 接口,工厂的接口,使用该接口可以获取到具体的Bean对象。该接口下有两个具体的实现类。

SpringCloud  配置中心

ClassPathXmlApplicationContext,加载类路径下的Spring配置文件。

FileSystemXmlApplicationContext,加载本地磁盘下的Spring配置文件。

小编提醒

        Spring IOC bean 默认是单例的,在IOC容器中只会存在一个bean的实例,无论一次还是多次调用,始终指向的是同一个bean对象

创建了两个对象:最后实际调用的还是同一个对象,从输出的地址相同可以看出

如果想变成多例,在配置文件里面bean标签scope属性加上参数控制单多例,也可以加上一个注解,也是scope属性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值