JAVAEE框架(2)Spring的使用

目录

一、Spring初识

二、创建Spring项目

1、创建一个 Maven 项目

2、在 Maven 项目中,添加 Spring 框架支持(spring-context,spring-beans)

3、创建一个启动类 和 main 方法

三、将 Bean 对象存储到容器(Spring)中

1.在 Spring 项目中添加配置文件。【如果不是第一次添加Bean对象可以跳过此步骤】

2.先创建⼀个 Bean对象,并将它注册到 Spring中。

3.获取并使用 Bean 对象。

四、Spring 注解实现更简单的读取和存储对象

前置工作:配置扫描路径

一、通过注解存储 Bean 对象

1、五大类注解

思考:五大类注解有何区别?

2、方法注解

二、通过注解获取 Bean 对象

两种注入关键字:

1.属性注入

2.构造方法注入

3.setter注入

对比:@Resource VS @Autowired 的区别

对比:三种注入方式的区别

4.一个Bean对象被注入多次怎么处理


一、Spring初识

什么是Spring?

 Spring 指的是 Spring Framework,它是⼀个开源框架,有着活跃⽽庞⼤的社区。Spring ⽀持⼴泛的应⽤场景,它可以让 Java 企业级的应⽤程序开发起来更简单。
⽤⼀句话概括 Spring:Spring 是包含了众多⼯具⽅法的 IoC 容器。

什么是loC?

IoC( Inversion of Control)是 “控制反转” 的意思, 也就是说 Spring 是⼀个 “控制反转” 的容器。

举个例子,比如我们在 A 类中,想去调用 B 类中的方法。

如果没有 IoC 容器的话,就需要在A类中创建一个 B 对象,这时就需要 new B() 或者使用已经创建出来的 B 对象,但无论是哪种情况,A 对象掌握了绝对的主动权。
如果引入 IoC 容器的话,当 A 类中需要使用 B 对象时,IoC 容器会主动创建出一个 B 对象,注入到 A 的类中。此时对象 A 就变成了被动方,控制权 “反转给了” Spring 框架,也就是 “控制反转”了。

我们可以看到,对象的创建和销毁的权利都交给 Spring 来管理了,它本身⼜具备了存储对象和获取对象的能力,这就是 IoC 容器。

注:Spring 会帮我们管理所有的对象,在 Spring 中对象叫做 Bean。我们可以将 Bean 存储到 Spring 容器中,也可以将 Bean 从 Spring 容器中取出来。

二、创建Spring项目

1、创建一个 Maven 项目

点击New Project,选择Maven,然后一路next。

2、在 Maven 项目中,添加 Spring 框架支持(spring-context,spring-beans)

在项⽬的 pom.xml 文件中,添加 Spring 框架的⽀持,xml 配置如下:

<dependencies>
   <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.3.RELEASE</version>
    </dependency>
  
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.2.3.RELEASE</version>
    </dependency>
</dependencies>

添加的框架有 spring-context:spring 上下文,还有 spring-beans:管理对象的模块。

3、创建一个启动类 和 main 方法

在 src.main.java目录下,创建一个 Java类,并写一个main方法。如果能够正常运行说明项目成功创建。

三、将 Bean 对象存储到容器(Spring)中

1.在 Spring 项目中添加配置文件。【如果不是第一次添加Bean对象可以跳过此步骤】

在resources文件夹下New一个File文件,命名为sping_config.xml,然后将以下代码拷贝至sping_config.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">

</beans>

2.先创建⼀个 Bean对象,并将它注册到 Spring中。

我们可以设置一个目录专门存放 Bean 对象。

然后为它写一个方法,可以如下所示:

public class User {
    public void sayHi(String name){
        System.out.println("你好"+name);
    }
}

此时我们需要将这个 Bean 对象存入 spring, 后面再从spring中读取到 User,然后调用里面的方法。

我们需要对 spring_config.xml 配置文件,进行如下操作。

    <bean id="user" class="com.beans.User">
    </bean>

简单来说,我们要将Bean对象存入Spring,是通过键值对的形式存储的(有点类似map)——key就是id,也就是Bean对象的别名(id 的值可以与类名不相同,可以任意起,只要自己记得);value是类本身所在的具体位置,注意要把类所在的详细路径写下来。然后我们在获取Bean对象时,就是通过 id 别名来找到对应的 Bean 对象。

3.获取并使用 Bean 对象。

分为以下三步:

1、获取 Spring 上下文对象。

在启动类main方法中,通过ApplicationContext类获取Spring上下文。这个类源自我们刚才引入的spring-context框架。

new的对象 ClassPathXmlApplicationContext("spring_config.xml") 是描述Bean对象所在的xml文件(刚刚我们才将其配置,注意不要写错)。获取上下文对象,其实就是获取配置文件里的全部对象。

2、再通过上下文对象提供的方法,获取我们自己需要使用的 bean 对象。

要获取我们需要使用的 bean 对象,只需要调用getBean方法,根据 id 取出相应的 bean 对象,强转成对象对应的类型。

3、拿到 bean 对象之后,就可以使用 bean 对象了。

演示代码如下:

//1.先得到spring上下文对象,ApplicationContext 或者 BeanFactory
ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
//ApplicationContext加载全部bean; BeanFactory按需加载

//2.根据上下文对象提供的方法获取到bean
User user=(User)context.getBean("user");//必须和spring里的id保持一致

//3.可以使用了
user.sayHi("张三");

以上,如果能正常打印,就说明我们通过 Spring ,成功地将对象进行了存储和读取操作。

ps. 当然,getBean有其他的重载方法,比如通过类名来获取,如下所示:

User user=context.getBean(User.class);

除了 ApplicationContext 之外,我们还可以使⽤ BeanFactory 来作为 Spring 的上下文。使用起来也是差不多的,不再赘述。我们接下来看更重要的,通过注解来实现更方便的存储和读取对象。

四、Spring 注解实现更简单的读取和存储对象

前置工作:配置扫描路径

因为我们不是采用手动的注入的方式了,而是使用自动扫描的方式。所以想要将对象成功的存储到 Spring 中,我们需要配置⼀下存储对象的扫描包路径,被配置的包路径下的所有添加了注解的类都会被自动识别并保存到 Spring 中。

步骤:在spring_config.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:content="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">  
    <content:component-scan base-package=""></content:component-scan>  
</beans>

这个base-package里面的内容需要我们自己添加,就是存放bean对象的根目录。

我们扫描的时候只扫描 base-package 里面的类 ,不在里面的类即使加入了注解也不会被扫

描。

效果如图所示:

思考:为什么要只加载特定目录里面的类呢?
因为不是所有的类都要把它放到Spring容器里面。有些普通的类对象并不会被别人使用,不需要注册到 Spring 里。所以我们只加载特定的要放入的类。

一、通过注解存储 Bean 对象

注:Spring 中的注解是通用的,在 Spring Boot 和 Spring MVC 中,也能够使用 Spring 的注解。 

1、类注解

1、@Controller 【Controller - 控制】
2、@Service 【service - 服务/业务】
3、@Repository 【repository - 仓库】
4、@Configuration 【configuration - 配置】
5、@Component 【component - 组件】
通过上述五大类注解中的任何一个,都可以将 bean 存储到 Spring 中。

举个例子:

我们只需要添加一个注解(五大类注解中任意一个都行),就可以将 bean 存入 Spring 中。现在我们还没讲到通过注解获取对象,所以仍然使用 ApplicationContext。我们看到能够正常输出打印,说明对象被正确地输入了。

 注:要存入 Spring 中的 bean,必须处于配置文件的根目录下,而且注解不可省略!

同理,将 @Controller 改成 @Service、@Repository、@Configuration、@Component,都是可以成功执行的。

思考:五大类注解有何区别?

在开发中为了描述每一个类所属的功能,让人直接了解当前类的用途,我们就引入了五大类注解来帮助区分。

@Configuration 配置类,一些负责配置信息的类,放在配置层。
@Controller 控制类,主要是验证前端发过来的参数,放在业务逻辑层。
@Service 服务类,数据的处理和接口的调用(Dao层的接口),放在服务层。
@Repository 仓库类,主要是对数据库的操作,也叫做Dao类,放在持久层。
@Component 组件类,一些外部实现的工具类。

2、方法注解

@Bean ,也可以将一个 bean 存储到 Spring 中。

类注解是添加到某个类上的,而方法注解是放到某个⽅法上的,也就是说这个方法的返回值是一个对象。

例子:

我们先创建一个User类,用于待会函数返回对象用。

然后创建一个UserBean类,写一个返回User对象的方法并加上@Bean注解。

 此时运行一下发现找不到这个对象。

这是因为@Bean 必须搭配五大类注解才能使用。我们需要在类前面加一个类注解,如下所示:

此时再运行就能成功获取该对象。

 注意:

1、@Bean写在方法的前面,五大类注解放在类的前面。

2.、@Bean 必须搭配五大类注解才能使用。

二、通过注解获取 Bean 对象

两种注入关键字:

@Autowired

@Resource

两种关键字均可使用。我们先看使用,下面再来介绍它们的区别。

1.属性注入

1.1演示使用 @Autowired 实现属性注入

先创建一个UserService类,实现一个方法

 然后将他注入到UserController的属性中

执行main函数获取UserController的对象,然后调用其方法,看是否能成功调用UserService对象的方法。如果成功,说明UserService对象成功注入到了UserController的属性中。

 1.2演示使用 @Resource 实现属性注入。

可以成功执行

2.构造方法注入

我们新建一个 UserController2 类,它有一个UserService对象。现在我们想通过构造方法+注解的方式注入对象,只要在构造方法前加上@Autowired。

  看下执行效果,能正常打印 ,说明注入成功。

对比传统构造方法和构造方法注入的区别:

以前写法,耦合度高,当UserService构造方法改变时,UserController构造方法要跟着变。

userService= new UserService();

构造注入写法,解耦合,直接获取UserService的对象来用,不依赖UserService构造方法。

this.userService=userService;

注:@Resource 注解不支持构造方法注入。

这里直接报错了 

3.setter注入

我们创建一个 UserController3 类,它有一个UserService对象。现在我们想通过set方法+注解的方式注入对象,只要在set方法前加上@Autowired。

能够正常输出,说明setter注入成功。

另外,@Resource也支持 Setter 注入。如下所示: 

对比:@Resource VS @Autowired 的区别

1、出身不同:
Autowired属于Spring框架
Resource属于Jdk
2、使用范围不同:
Autowired可以作用于构造方法注入、属性注入、setter注入
Resource可以作用于属性注入、setter注入
3、参数个数不同
Autowired只有一个参数:required
Resource有多个参数:name,、lookup、type,…

对比:三种注入方式的区别

  • 属性注入使用方便。但是缺点是只能适用于IoC容器,在非IoC容器不适用。
  • 构造方法注入是最推荐的注入方式。 缺点是如果注入多个对象,就会包含多个参数。优点通用性强,在使用前一定可以保证属性构造好了。
  • Setter方式注入是Spring前期推荐的注入方式,针对一个参数进行构造,通用性不如构造方法注入。

4.一个Bean对象被注入多次怎么处理

如果一个Bean的对象被注入了多次,那么获取对象的时候怎么区分到底是哪一个对象呢?

例如UserBean类有两个对象注册到了Spring里,此时注入

 此时直接注入会报如下的错误,提示找到了两个对象。

 解决办法:

1.注入时直接写Bean对象的名字

直接清楚的描述类的名字。
使用@Resource和@Autowired属性注入的方式,但被注入属性对象名要和注入对象的名字一样

首先为这两个对象取个不同的名字,以便注入区分。

扩展——@Bean重命名

当@Bean 没有设置 name 属性时,那么 beanName 默认就是方法名。
但是这样的话,注入对象时就要通过方法名来获取bean对象,很不方便(获取的是 bean,却填一个方法名)。所以可以通过设置@Bean的name属性来对方法重命名,写法如下:@Bean(name="xxx"),或者@Bean(name={"xxx1", "xxx2"})。

当设置 name 属性之后, name 属性对应的值,就是 beanName,而且属性的值可以有多个。但是此时方法名就不可以使用了。

此时注入user1,只需要将属性名改成一样的名字,就可以获得user1的信息

 注入user2,即可获得user2的信息

2.使用@Resource的name属性

如果觉得属性名必须要和注入对象名完全一致很麻烦,那么可以在@Resource的name属性中设置对象的名字(name="xxx"),写什么名字就注入什么名字的对象。

 这样属性名既可以随便取,也能获取对应的Bean对象。

3.使用@Autowired+@Qualifier

这种方法和@Resource异曲同工。因为Autowired没有name属性,所以我们采用Qualifier来帮助我们。@Qualifier 注解相当于一个筛选器,对 @Autowired注解查询的结果进行筛选。

 


总结

本文介绍了Spring的基本使用,接下来去我会介绍 Spring Boot 的使用方法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值