Spring框架学习 -- 创建与使用

简介: Spring框架学习 -- 创建与使用


(1) 创建spring 项目

       首先我们使用的开发工具为idea 专业版.

       想要创建一个spring项目, 首先需要使用到maven, 所以我们创建spring项目的方式和servelet类似, 可以总结为下面几个步骤:

  1. 创建一个maven项目
  2. 添加spring的框架支持
  3. 添加启动类

       下面我们来依次分析这几个步骤

创建maven项目

       这个想必大家都很熟, 如果不知道如何创建maven项目的可以参考我的其他文章.

②添加spring框架支持

       首先我们需要在pom.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:管理对象的模块.

       接下来配置spring设置文件, 如下:

我们在resources目录中创建文件 springConfig.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>

        然后刷新(reload)Maven项目:

       如果下载速度慢的话, 是因为maven仓库在国外, 访问速度很慢, 这个时候就需要配置国内源, 具体如何配置国内源, 大体就是在maven的setting.xml文件中设置国内源镜像结点, 具体如何操作可以自行搜索.

③ 添加启动项

       也就是添加主类, 这个和普通程序无异.

(2) 创建 Bean对象

       只有先创建Bean对象, 才能把对象注入到容器中去, 首先我们应该学习如何创建Bean对象.

       首先我们先创建一个User类如下:

public class User {
    public void sayHi() {
        System.out.println("hello, how are you?");
    }
}

       所谓的Bean对象, 其实就是java里面一个类的对象.

       然后将Bean注入到容器

(3) 将Bean注入到容器

       在我们配置好的springConfig.xml文件中的注入Bean, 如下:

        下面我们来看看springConfig.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="user" class="org.example.User"></bean>
</beans>

       其中 一个 标签, 就代表一个bean对象, class是指的类的路径, 指明注入的是哪个类, id是这个类对象的名称, 方便于后面取出这个对象.

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

(4) 获取Bean对象

       获取Bean对象大致可以分为下面几步:

  • 得到spring的上下文支持, 因为对象都交给spring管理了, 所以要获取注入到spring容器中的类就需要得到spring的上下文
  • 通过spring的上下文对象, 获取到指定的Bean对象
  • 使用Bean对象

       

       首先获取spring上下文:

public class Main {
    public static void main(String[] args) {
        // 创建BeanFactory
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
 
        // 创建读取器
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
 
        // 加载配置文件
        reader.loadBeanDefinitions("springConfig.xml");
 
        // 获取Bean实例对象
        User user = (User)beanFactory.getBean("user");
        user.sayHi();
    }
}

       这样子分为了四步, 对于记忆这方面也比较繁琐, 于是java将上面这三个步骤封装成一个步骤, 也就是下面的这个ApplicationContext类:  

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("springConfig.xml")
                
    }
}

       其中ApplicationContext就是spring的上下文类, ClassPathXmlApplicationContext是他的具体实现类. ClassPathXmlApplicationContext中的参数为我们配置好的spring配置文件名: springConfig.xml

       除了ApplicationContext之外, 还可以使用BeanFactory类来获取spring上下文, 具体操作为:

public class Main {
    public static void main(String[] args) {
        BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("springConfig.xml"));
 
    }
}

       ApplicationContext 和 BeanFactory 效果是⼀样的,ApplicationContext 属于 BeanFactory 的⼦类,

       那么ApplicationContext和BeanFactory具体有什么区别? (这是一个常见的面试题)

  • 继承关系和功能方面来说: Spring容器有两个顶级的接口, 那就是BeanFactory 和ApplicationContext, 其中BeanFactory提供了基础访问容器的能力, 而ApplicationContext属于BeanFactory的子类, 它除了继承了BeanFactory的所有功能之外, 它还拥有其他独特的特性, 还添加了对国际化的支持, 资源访问支持, 以及事件传播等方面的支持
  • 从性能来说, ApplicationContext是一次性加载并初始化所有的Bean对象, 而BeanFactory是需要哪个才去加载哪个, 因此BeanFactory更加的轻量. 而ApplicationContext加载慢但是使用(这里的使用是指的取出Bean对象)非常的快速.

       然后就是如何获取Bean对象了, spring的上下文对象中提供了一个getBean方法, 用来获取指定的对象, 他的参数为一个字符串, 用来指定一个Bean对象的id  , 如下:

// 1.得到 Spring 上下⽂对象
ApplicationContext context = new ClassPathXmlApplicationContext("springcon
fig.xml");
// 2.加载某个 bean
User user = (User) context.getBean("user");

        此处我们再回过头来看看我们注入的类:

       此处的路径为: org.example.User,  springConfig.xml中的文件中注入的Bean如下:

<bean id="user" class="org.example.User"></bean>

        可以看出这个路径和对象是一一对应的.

        获取到Bean之后, 使用Bean对象就可以像普通开发程序中那样使用类了:

        BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("springConfig.xml"));
        User user = (User)beanFactory.getBean("user");
        user.sayHi();

       -- 输出:

       需要注意的是, getBean方法返回的是Object类型, 因此使用的时候还需要强制类型转换, 将其转换为对应的类才可以使用, 或者是使用getBean的重载方法, 里面有两个参数, 一个是字符串对象, 代表要使用的Bean对象的id,  第二个参数是使用反射来获取这个对象所属的类:

        BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("springConfig.xml"));
        User user = beanFactory.getBean("user", User.class);
        user.sayHi();

       此时getBean就会直接返回get的Bean对象的类型.

       下面是其原码的定义 :

(5) 注意事项

       spring配置文件的容器中注入的Bean对象的id要和getBean中的id一致:

        除此之外, 我们在获取Bean对象的时候, 其实也可以直接传入一个Bean对应的类就可以将其取出来:

      sping 配置文件如下:

<?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="org.example.User"></bean>
</beans>

       main方法中来获取这个id为user的Bean对象, 但是我们getBean的时候只传入这个类, 而不是这个类的id名:

        BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("springConfig.xml"));
        User user = beanFactory.getBean(User.class);
        user.sayHi();

       运行 -- 输出如下:

       可以看出来, 可以成功取出Bean然后使用此Bean对象

       但是我们思考一下, 任何情况下都能这样获取到Bean对象吗? 显然不是, 我们传入的是对应的Bean对象的类, 因此我们传入的是类名, 但是想想, 如果我们在spring容器中注入两个相同的类对象, 但是id不同, 再次使用传入类名的情况会成功吗?

<?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="user1" class="org.example.User"></bean>
        <bean id="user2" class="org.example.User"></bean>
</beans>

       可以看到spring容器中已经被注入了两个Bean对象, 这两个Bean对象都属于User类, 我们再次去使用getBean(Class var) 的方法去获取Bean对象

       Bean对象获取:

        BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("springConfig.xml"));
        User user = beanFactory.getBean(User.class);
        user.sayHi();

       -- 输出:

Exception in thread "main" org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.example.User' available: expected single matching bean but found 2: user1,user2
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1180)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveBean(DefaultListableBeanFactory.java:416)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:349)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)
  at org.example.Main.main(Main.java:12)

       关键报错信息展示:

Exception in thread "main" org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.example.User' available: expected single matching bean but found 2: user1,user2

       可以翻译一下就是:

        可以看出找到了两个Bean对象: user1 和 user2, 但是spring不知道使用哪一个, 所以报错.

(*) xml注入Bean对象id和name属性

       我们在注入一个Bean对象的时候, 如下:

<bean id="userController" name="aaa,bbb,ccc" class="com.java.demo.Controller.UserController"></bean>

        我们给这个Bean对象取了一个id, 然后又给了name属性设置了三个名字, 他们之间尊崇这样的原则:

  • 如果只有id, 那么这个Bean的name就为这个id里的内容
  • 如果只有name, 那么这个name属性的第一个值就为Bean的name.
  • 如果既有id又有name属性, 那么BeanName就为这个id, 同时你也可以通过别名来获取这个Bean对象.

       解释, 这个name属性, 也就是 Bean的别名, 被维护在一个aliasMap的Map中. 也就是后面可以通过在这个map里面获取别名的形式来获取这个Bean对象.

(6) Spring的创建和使用流程图



目录
相关文章
|
10天前
|
XML 安全 Java
|
13天前
|
缓存 NoSQL Java
什么是缓存?如何在 Spring Boot 中使用缓存框架
什么是缓存?如何在 Spring Boot 中使用缓存框架
19 0
|
1月前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
2月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
52 4
|
2月前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
41 0
|
6天前
|
缓存 Java 数据库连接
Spring框架中的事件机制:深入理解与实践
Spring框架是一个广泛使用的Java企业级应用框架,提供了依赖注入、面向切面编程(AOP)、事务管理、Web应用程序开发等一系列功能。在Spring框架中,事件机制是一种重要的通信方式,它允许不同组件之间进行松耦合的通信,提高了应用程序的可维护性和可扩展性。本文将深入探讨Spring框架中的事件机制,包括不同类型的事件、底层原理、应用实践以及优缺点。
38 8
|
16天前
|
存储 Java 关系型数据库
在Spring Boot中整合Seata框架实现分布式事务
可以在 Spring Boot 中成功整合 Seata 框架,实现分布式事务的管理和处理。在实际应用中,还需要根据具体的业务需求和技术架构进行进一步的优化和调整。同时,要注意处理各种可能出现的问题,以保障分布式事务的顺利执行。
32 6
|
21天前
|
Java 数据库连接 数据库
不可不知道的Spring 框架七大模块
Spring框架是一个全面的Java企业级应用开发框架,其核心容器模块为其他模块提供基础支持,包括Beans、Core、Context和SpEL四大子模块;数据访问及集成模块支持数据库操作,涵盖JDBC、ORM、OXM、JMS和Transactions;Web模块则专注于Web应用,提供Servlet、WebSocket等功能;此外,还包括AOP、Aspects、Instrumentation、Messaging和Test等辅助模块,共同构建强大的企业级应用解决方案。
41 2
|
2月前
|
前端开发 Java 数据库连接
Spring 框架:Java 开发者的春天
Spring 框架是一个功能强大的开源框架,主要用于简化 Java 企业级应用的开发,由被称为“Spring 之父”的 Rod Johnson 于 2002 年提出并创立,并由Pivotal团队维护。
63 1
Spring 框架:Java 开发者的春天
|
1月前
|
前端开发 Java 开发者
Spring生态学习路径与源码深度探讨
【11月更文挑战第13天】Spring框架作为Java企业级开发中的核心框架,其丰富的生态系统和强大的功能吸引了无数开发者的关注。学习Spring生态不仅仅是掌握Spring Framework本身,更需要深入理解其周边组件和工具,以及源码的底层实现逻辑。本文将从Spring生态的学习路径入手,详细探讨如何系统地学习Spring,并深入解析各个重点的底层实现逻辑。
55 9