Spring(ioc)

目录

一、为什么要使用Spring?

1.1、程序的耦合和解耦合

问:以前写的代码有什么问题?

二、IOC

2.1、为什么要使用IOC?

2.1、IDEA中使用IOC

三、切片1:通过xml使用IOC

3.1、注入Java实体

3.1.1、需求定义

3.1.2、需求实现

3.1.3、案例1

创建汽车实体类

carBeans.xml配置文件

创建测试类

运行结果

四、切片2:通过注解使用IOC

4.1、知识点讲解

4.1.1、@Component

4.1.2、@Component衍生的注解

4.1.3、用于注入数据的注解

4.1.4、@ Scope

五、Spring5的新注解

5.1、@Configuration

5.2、@ComponentScan

5.3、综合应用


一、为什么要使用Spring?

Spring 是个java企业级应用的开源开发框架。Spring主要用来开发Java应用,但是有些扩展是针对构建J2EE平台的web应用。Spring 框架目标是简化Java企业级应用开发,并通过POJO为基础的编程模型促进良好的编程习惯。

为什么要使用Spring?原因很简单,Spring有很多特点:

轻量: Spring 是轻量的,基本的版本大约2MB。

控制反转: Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。

面向切面的编程(AOP): Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。

容器: Spring 包含并管理应用中对象的生命周期和配置。

MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品。

事务管理: Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务

1.1、程序的耦合和解耦合

藕合就是程序间的依赖关系。解藕就是降低程序间的依赖关系。在开发过程中应做到编译期不依赖,运行时再依赖。

解藕思路:
​
1、使用反射来创建对象,而不使用new关键字
​
2、通过读取配置文件来获取要创建的对象全限定名

问:以前写的代码有什么问题?

创建java控制台程序

创建DAO

 创建service并调用Dao

 创建测试类并调用service

层与层之间的关系通过new来实现调用,并且new对象时需要导入该对象所在的正确的包名,否则报错。这种关系称为耦合关系。

二、IOC

2.1、为什么要使用IOC?

IOC呢,也就是控制反转,它的核心思想就是把对象的管理权交给了容器,那么,应用程序如果需要使用某个对象的实例,就可以直接从IOC容器里获取了。

 我认为,这种设计的好处就在于降低了程序中对象与对象之间的耦合性,使得程序的整个体系结构变得更加灵活。

2.1、IDEA中使用IOC

第1步:创建一个普通Maven项目

第2步:添加依赖

在pom.xml中添加依赖

  <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.0.RELEASE</version>
        </dependency>
    </dependencies>

三、切片1:通过xml使用IOC

3.1、注入Java实体

3.1.1、需求定义

使用IOC实现User对象的注入

3.1.2、需求实现

User.java的创建

package practice.entity;
​
public class User {
    private int id;
    private String name;
    private Date birth;
​
    //Get和Set方法,重写toString方法
}
​

beans.xml配置文件

 

 按图操作,将beans.xml配置文件设置成一个应用程序的上下文文件

注入User对象的信息

在beans中配置User的信息,设定user的姓名等属性。

<?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="user" class="practice.entity.User">
        <property name="id" value="1001"></property>
        <property name="name" value="二哈"></property>
        <!-- 引用日期对象 -->
        <property name="birth" ref="date_ref"></property>
    </bean>

    <!-- 实例化日期对象 -->
    <bean id="date_ref" class="java.util.Date"></bean>
</beans>

创建测试类进行测试

#### 

```
package practice;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import practice.entity.User;

public class Test {
    public static void main(String[] args) {
        //在配置文件中获取应用程序上下文
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //从ioc容器中获取User对象,并注入到myUser中
        User myUser = (User) context.getBean("user");
        System.out.println(user.toString());
    }
}
```


3.1.3、案例1

需求:
1、创建一个汽车类,类中有属性:车牌(String)、品牌(String)、出场日期(Date)属性
2、创建汽车对象,完成初始化,并注入到IOC容器
3、创建一个新的汽车对象的引用myCar,然后从IOC容器中获取汽车对象,并注入到myCar中
4、打印输出myCar的所有属性内容

创建汽车实体类

package demo;

import java.util.Date;

public class Car {
    private String number;
    private  String brand;
    private Date birth;

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    public Car(String number, String brand, Date birth) {
        this.number = number;
        this.brand = brand;
        this.birth = birth;
    }

    public Car() {
    }

    @Override
    public String toString() {
        return "Car{" +
                "number='" + number + '\'' +
                ", brand='" + brand + '\'' +
                ", birth=" + birth +
                '}';
    }
}

carBeans.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="car" class="demo.Car">
        <property name="number" value="京A99999"/>
        <property name="brand" value="迈巴赫"/>
        <property name="birth" ref="ref_date"/>
    </bean>
    <bean id="ref_date" class="java.util.Date"/>
</beans>

创建测试类

import demo.Car;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test1 {
    public static void main(String[] args) {
       ApplicationContext context = new ClassPathXmlApplicationContext("carBeans.xml");
        Car car = (Car) context.getBean("car");
        System.out.println(car);
    }

}

运行结果

四、切片2:通过注解使用IOC

注解配置和 xml配置要实现的功能都是一样的,都是要降低程序间的耦合。只是配置的形式不一样。关于实际的开发中到底使用 xml还是注解,每家公司有着不同的使用习惯。

4.1、知识点讲解

4.1.1、@Component

用于创建对象的注解

相当于:<bean id="" class="">

作用: 把资源让 spring 来管理。相当于在 xml 中配置一个 bean。 属性: value:指定 bean 的 id。如果不指定 value 属性,默认 bean 的 id 是当前类的类名。首字母小写。

代码演示

User实体类

定义一个User实体类,通过@Component将该类的对象注入到IOC容器

package practice.entity;

import org.springframework.stereotype.Component;

@Component
//@Component("uuu")
public class UserInfo {
    public void showUser(){
        System.out.println("我叫二哈,今年18岁");
    }
}

beans.xml配置类

在配置类中我们通过component-scan注解扫描所有使用注解的类

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

    <!-- 扫描注解类 -->
    <context:component-scan base-package="practice"/>
</beans>

测试类

> 

```
package practice;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import practice.entity.User;

public class Test1 {
    public static void main(String[] args) {
        //读取Spring的核心配置文件
        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
        //从IOC容器中获取User对象
        User usr = (User) ctx.getBean("userInfo");
        usr.showUser();
    }
}


4.1.2、@Component衍生的注解

除了上面使用到的Component注解外还有几个常用的注解: @Component: 用于任意类的注入 @Repository: 用于标识在dao类上 @Service: 用于标识在Service类上 @Controller: 用于标识在控制器类上

Ps:使用方式和@Component一样

4.1.3、用于注入数据的注解

相当于:<property name="" ref="">

4.1.3.1、@Autowired

按照Bean的类型,从IOC容器中获取对象进行装配。

代码演示

UserInfo实体类

//@Component("uuu")
//@Component
@Repository
public class UserInfo {

    public void showUserInfo(){
        System.out.println("我叫二哈,今年18岁");
    }
}

UserService

通过@Autowired注解从ioc容器获取UserInfo对象

@Service
//@Scope("singleton") //单例
@Scope("prototype") //多例
public class UserService {

    @Autowired
    //@Resource
    private UserInfo userInfo;

    public void showUser(){
        System.out.println("哈哈哈,我是userService");
        userInfo.showUserInfo();
    }
}

beans.xml

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

    <!-- 扫描注解类 -->
    <context:component-scan base-package="practice"/>
</beans>

测试类

package practice;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test1 {

    public static void main(String[] args) {
        //读取Spring的核心配置文件
        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
        //从IOC容器中获取User对象
        UserService userService = (UserService) ctx.getBean("userService");
        userService.showUser();
    }
}

4.1.4、@ Scope

@ Scope注解:用于指定bean的作用范围,属性value:指定范围的取值。 常用取值:singleton(单例)、 prototype(多例)和生命周期相关,他们的作用就和在bean标签中使用init-method和destroy-methode的作用是一样的

案例:演示单例模式

修改service实现类

修改service实现类

@Service
//@Scope("singleton") //单例
@Scope("prototype") //多例
public class UserService {

//    @Autowired
    @Resource
    private UserInfo userInfo;

    public void showUser(){
        System.out.println("哈哈哈,我是userService");
        userInfo.showUserInfo();
    }
}

修改测试类

package demo1;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test2 {
    public static void main(String[] args) {
        ApplicationContext cxt = new ClassPathXmlApplicationContext("beans.xml");
        UserService userService = (UserService) cxt.getBean("userService");
        userService.showUser();
        UserService userService1 = (UserService) cxt.getBean("userService");
        System.out.println(userService == userService1);
    }
}

五、Spring5的新注解

spring的核心配置文件除了可以用xml之外还可以使用一个java类来代替xml配置文件。如果要使用java类做为核心配置类,需要使用特定的注解,这些注解是在spring 5的版本中新加的

5.1、@Configuration

用于指定当前类是一个 spring 配置类,当创建容器时会从该类上加载注解。获取容器时需要使用AnnotationApplicationContext(有@Configuration 注解的类.class)。 

5.2、@ComponentScan

用于指定 spring 在初始化容器时要扫描的包。作用和在 spring 的 xml 配置文件中的:
<context:component-scan base-package="com "/>是一样的
属性: basePackages:用于指定要扫描的包。和该注解中的 value 属性作用一样
语法:
@ComponentScan(basePackages = {"要扫描的包名1","要扫描的包名2",...})

5.3、综合应用

@Configuration和@ComponentScan的综合应用,零配置文件实现IOC

修改之前切片2的案例

第1步:将beans.xml配置文件删除

第2步:添加配置文件

使用@Configuration注解定义配置类,使用@ComponentScan注解开启注解的自动扫描

package demo2;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan({"demo2"})
public class SpringConfig {

}

第3步:添加要注入到ioc容器的实体

package demo2;

import org.springframework.stereotype.Component;

@Component
public class UserIntro {

    public void showUserInfo(){
        System.out.println("我叫二哈,今年18岁");
    }
}

第4步:修改测试类

通过AnnotationApplicationContext获取IOC容器


package demo2;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {
    public static void main(String[] args) {
        ApplicationContext cxt = new AnnotationConfigApplicationContext(SpringConfig.class);
        UserIntro intro = (UserIntro) cxt.getBean("userIntro");
        intro.showUserInfo();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值