Spring知识篇2:Spring Frame框架的基本知识

1. IOC和DI

1.1 概念

  • ioc就是控制反转,在Spring中,对象的属性是由对象自己创建的,就是正向流程;如果属性不是对象创建的,而是由Spring来自动进行装配,就是控制反转。这里的DI也就是依赖注入,就是实现控制反转的方式。正向流程导致了对象于对象之间的高耦合,IOC可以解决对象耦合的问题,有利于功能的复用,能够使程序的结构变得灵活。
  • 依赖注入和控制反转的定义相同,它们是从两个角度描述用一个概念。当某个java实例需要另一个java实例的时候,传统的方法是由调用者创建创建被调用者的实例,而使用Spring框架后,被调用者的实例不再由调用者创建,而是由Spring容器创建,这就是控制反转。

1.2 依赖注入的实现方式

  • 属性setter注入:指IOC容器使用setter方法注入被依赖的实例。通过调用无参构造器或无参static工厂方法实例化bean后,调用该bean的setter方法,即可实现基于setter的DI。
  • 构造方法注入:指IOC容器使用构造方法注入被依赖的实例,基于构造器的DI通过调用带参数的构造方法实现,每个参数代表一个依赖。

2. context上下文和bean

2.1 概念

  • Spring进行IOC实现时使用的有两个概念:context上下文和bean。
    所有被Spring管理的、由Spring创建的、用于依赖注入的对象,就叫做一个bean。
    Spring创建并完成依赖注入后,所有的bean统一放在一个叫做context的上下文中进行管理。

2.2 bean的配置及常用属性

Spring 容器可以被看作一个大工厂,而 Spring 容器中的 Bean 就相当于该工厂的产品。如果希望这个大工厂能够生产和管理 Bean,这时则需要告诉容器需要哪些 Bean,以及需要以何种方式将这些 Bean 装配到一起。

  • Spring配置文件支持两种不同的格式,分别是XML文件格式和Properties文件格式。通常情况下,Spring会以XML文件格式作为Spring的配置文件,这种配置方式通过XML文件注册并管理Bean之间的依赖关系。
    (1)XML格式配置文件的根元素是,该元素包含了多个子元素,每一个子元素定义了一个Bean,并描述了该Bean如何被装配到Spring容器中。

    • 定义Bean的实例代码如下所示:
<?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
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
    <!-- 使用id属性定义person1,其对应的实现类为com.mengma.person1 -->
    <bean id="person1" class="com.mengma.damain.Person1" />
    <!--使用name属性定义person2,其对应的实现类为com.mengma.domain.Person2-->
    <bean name="Person2" class="com.mengma.domain.Person2"/>
</beans>
  • 上述的代码中,分别使用 id 和 name 属性定义了两个 Bean,并使用 class 元素指定了 Bean 对应的实现类。

(2)Porperties类是键和值均为字符串的可以永久存储到文件中的key-value组合。

  • 如何配置可以参考这个文章:传送门
    配置好后如何加载Properties文件的四种格式:传送门

(3)元素中包含了很多的属性,常用的属性有:
在这里插入图片描述

2.3 Spring实例化Bean的三种方法

  • 在面向对象的程序中,要想调用某个类的成员方法,就需要先实例化该类的对象。在Spring中,实例化Bean有三种方式,分别是构造器实例化、静态工厂方式实例化和实例工厂方式实例化
    (1)构造器实例化:构造器实例化是指Spring容器通过Bean对应的类中默认的构造函数实例化Bean。
    (2)静态工厂实例化:此种方式需要提供一个静态工厂方法创建Bean的实例。
    (3)实例工厂方式实例化:在这种方式中,工厂类不在使用静态方法创建Bean的实例,而是直接在成员方法中创建Bean的实例。

2.4 Spring中Bean的作用域

  • 共有5种,其中重点是singleton和prototype这两种最常用的作用域。
    (1)singleton:单例模式,使用singleton定义的Bean在Spring容器中只有一个实例,这也是Bean默认的作用域。
    (2)prototype:原型模式,每次通过Spring容器获取prototype定义的Bean时,容器都会创建一个新的Bean实例。
    (3)request:在一次http请求中,容器会返回该Bean的同一个实例。而对不同的http请求,会返回不同的实例,该作用域仅在当前http request内有效。
    (4)session:在一次http Session中,容器会返回该Bean的同一个实例,而对不同的http请求,会返回不同的实例,该作用域仅在当前http request内有效。
    (5)global Session:在一次全局的http Session中,容器会返回该Bean的同一个实例,该作用域仅在当前http request内有效。

  • 我们重点说说singleton和prototype两种作用域
    (1)singleton作用域:当一个Bean的作用域为singleton时。Spring容器只会存在一个共享的Bean实例,并且所有对Bean的请求,只要id与该Bean定义相匹配,就只会返回Bean的同一个实例。
    通常情况下,这种单例模式对于无会话状态的Bean(如DAO层,Service层)来说,是最好的选择。
    在 Spring 配置文件中,可以使用 元素的 scope 属性,将 Bean 的作用域定义成 singleton,其配置方式如下所示:

<bean id="person" class="com.mengma.scope.Person" scope="singleton"/>

(2)prototype作用域
使用 prototype 作用域的 Bean 会在每次请求该 Bean 时都会创建一个新的 Bean 实例。因此对需要保持会话状态的 Bean(如 Struts2 的 Action 类)应该使用 prototype 作用域。
在 Spring 配置文件中,要将 Bean 定义为 prototype 作用域,只需将 元素的 scope 属性值定义成 prototype,其示例代码如下所示:

<bean id="person" class="com.mengma.scope.Person" scope="prototype"/>

2.5 Spring Bean的生命周期

  • Spring容器可以管理singleton作用域的生命周期,在此作用域下,Spring能够精确的直到该Bean何时被创建,何时初始化完成,以及何时被销毁。
  • 而对于prototype作用域的Bean,Spring只负责创建,当容器创建了Bean的实例后,Bean的实例就交给客户端代码管理,Spring容器将不再跟踪器生命周期。每次客户端请求 prototype 作用域的 Bean 时,Spring 容器都会创建一个新的实例,并且不会管那些被配置成 prototype 作用域的 Bean 的生命周期。
  • 当一个Bean被加载到Spring容器中时,它就具有了生命,而Spring容器在保证一个Bean能够工作之前,会进行很多的工作,其在Spring容器中的生命周期如图:
    在这里插入图片描述
  • Bean生命周期的执行过程如下:
    (1)根据配置情况调用Bean构造方法或工厂方法实例化Bean。
    (2)利用依赖注入完成Bean中所有属性值的配置注入。
    (3)如果Bean实现了BeanNameAware接口,则Spring调用Bean的setBeanName()方法传入当前Bean的id值。
    (4)如果Bean实现了BeanFactorAware接口,则Spring调用setBeanFactor()方法传入当前工厂实例的引用。
    (5)如果Bean实现了ApplicationContextAware接口,则 Spring 调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。
    (6)如果BeanPostProcessor和Bean关联,则Spring将调用该接口的预初始化方法postProcessBeforeInitialzation() 对 Bean 进行加工操作,此处非常重要,Spring 的 AOP 就是利用它实现的。
    (7)如果 Bean 实现了 InitializingBean 接口,则 Spring 将调用 afterPropertiesSet() 方法。
    (8)如果在配置文件中通过init-method属性指定了初始化方法,则调用该初始化方法。
    (9)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的初始化方法 postProcessAfterInitialization()。此时,Bean 已经可以被应用系统使用了。
    (10)如果在 中指定了该 Bean 的作用范围为 scope=“singleton”,则将该 Bean 放入 Spring IoC 的缓存池中,将触发 Spring 对该 Bean 的生命周期管理;如果在 中指定了该 Bean 的作用范围为 scope=“prototype”,则将该 Bean 交给调用者,调用者管理该 Bean 的生命周期,Spring 不再管理该 Bean。
    (11)如果Bean 实现了DisposableBean接口,则Spring会调用destory()方法将Spring中的Bean销毁;如果在配置文件咱通过destory-method属性指定了Bean的销毁方法,则Spring将调用该方法对Bean进行销毁。

2.6 Spring对于Bean的装配

  • Bean的装配可以理解为依赖关系注入,Bean的装配方式也就是Bean的依赖注入方式。
2.6.1 基于XML装配Bean的方式
  • 基于XML装配Bean的方式,通常有两种实现方式,即设值注入和构造注入
  • 在Spring实例化Bean的过程中,首先调用默认的构造方法实例化Bean对象,然后通过Java的反射机制调用setXXX()方法进行属性的注入。因此,设值注入要求一个Bean的对应类必须满足下面的要求:
    (1)必须提供一个默认的无参构造方法
    (2)必须为需要注入的属性提供对应的setter方法
  • 使用设值注入时,在Spring配置文件中,需要使用 元素的子元素 元素为每个属性注入值。
  • 而使用构造注入时,在配置文件中,主要使用< constructor-arg >标签定义构造方法的参数,可以使用其 value 属性(或子元素)设置该参数的值。
<?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
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
    <!-- 使用设值注入方式装配Person实例 -->
    <bean id="person1" class="com.mengma.assembly.Person">
        <property name="name" value="zhangsan" />
        <property name="age" value="20" />
    </bean>
    <!-- 使用构造方法装配Person实例 -->
    <bean id="person2" class="com.mengma.assembly.Person">
        <constructor-arg index="0" value="lisi" />
        <constructor-arg index="1" value="21" />
    </bean>
</beans>
2.6.2 基于Annotation装配Bean

在这里插入图片描述

  • 常用的注解有很多,大体如下:
    (1)@Component --> 中文意为组件,音标为 /kəmˈpəʊnənt/
    可以使用此注解描述Spring中的Bean,但它是一个泛化的概念,仅仅表示一个组件(Bean),并且可以作用在任何层次,使用时只需将该注解标注在相应的类上即可。
    (2)@Repository -->中文意为仓库,音标为 /rɪˈpɒzətri/
    用于将数据访问层(DAO层)的类的标识为Spring的Bean,其功能与@Component相同。
    (3)@Service
    通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
    (4)@Controller
    通常作用在控制层(如 Struts2 的 Action),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
    (5)Autowired -->中文意为自动装配
    用于堆Bean的属性变量、属性的Set方法及构造函数进行标注,配合对应的注解处理器完成Bean的自动装配工作,默认按照Bean的类型进行装配。
    (6)Resource
    其作用和Autowired一样,其区别在于@Autowired默认按照Bean类型装配,而@Resource默认按照Bean实例名称进行装配。
    @Resource中两个重要属性:name和type。
    String将name属性解析为Bean实例名称,type属性解析为Bean实例类型。如果指定name属性,则按实例名称进行装配;如果指定type属性,则按Bean类型进行装配。
    如果都不指定,则先按Bean实例名称进行装配,如果不能匹配,则按照Bean类型进行装配;如果都无法匹配,则抛出NoSuchBeanDefinitionException异常。
    (7)Qualifier -->中文意为修饰语 音标为 /ˈkwɒlɪfaɪə®/
    与@Autowired注解配合使用,会将默认的按Bean类型装配修改为按Bean的实例名称进行装配,Bean的实例名称由@Qualifier注解的参数指定。
2.6.3 Spring自动装配Bean
  • 除了使用XML和Annotation的方式装配Bean以外,还有一种常见的装配方式:自动装配。自动装配就是指Spring容器可以自动装配(Autowire)相互协作的Bean之间的关联关系,将一个Bean注入其他Bean的Property中。
    要使用自动装配,就需要配置元素的autowire属性,autowire属性有5个值,如下图。
    在这里插入图片描述
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为你提供一个使用Spring框架的案例程序来实现将嵌入式开发板采集的数据实时传输到一个网页的功能。以下是一个简单的示例: 1. 创建Spring Boot项目:使用Spring Initializr(https://start.spring.io/)创建一个新的Spring Boot项目。选择所需的依赖项,如Spring Web和Spring WebSocket。 2. 定义数据模型:创建一个Java类来表示采集的数据模型。例如,假设你要采集温度数据,可以创建一个名为"TemperatureData"的类,并定义相应的属性。 ```java public class TemperatureData { private double temperature; // getters and setters } ``` 3. 创建WebSocket控制器:创建一个WebSocket控制器类,用于处理与网页的实时通信。在该类中,使用`@Controller`和`@MessageMapping`注解来定义WebSocket端点,并编写处理来自嵌入式设备数据的方法。 ```java @Controller public class DataWebSocketController { @MessageMapping("/temperature") @SendTo("/topic/temperature") public TemperatureData handleTemperatureData(TemperatureData data) { // 处理来自嵌入式设备的数据 // 存储数据或其他处理逻辑... return data; } } ``` 4. 配置WebSocket:在配置类中启用WebSocket支持,并配置WebSocket消息代理。 ```java @Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableSimpleBroker("/topic"); registry.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/ws").withSockJS(); } } ``` 5. 创建网页:创建一个HTML网页,使用JavaScript和STOMP.js库来建立WebSocket连接并实时接收来自服务器的数据。 ```html <!DOCTYPE html> <html> <head> <title>实时温度数据</title> <script src="https://cdn.jsdelivr.net/npm/stompjs"></script> <script src="https://cdn.jsdelivr.net/npm/sockjs-client"></script> <script> var stompClient = null; function connect() { var socket = new SockJS('/ws'); stompClient = Stomp.over(socket); stompClient.connect({}, function (frame) { console.log('Connected: ' + frame); stompClient.subscribe('/topic/temperature', function (data) { var temperature = JSON.parse(data.body).temperature; document.getElementById("temperature").innerText = temperature; }); }); } window.onload = function() { connect(); }; </script> </head> <body> <h1>实时温度数据</h1> <p>当前温度: <span id="temperature"></span></p> </body> </html> ``` 以上示例代码展示了一个简单的使用Spring框架的案例程序。你可以根据自己的需求进行进一步的修改和扩展。确保在项目中包含必要的依赖项,如Spring Web和Spring WebSocket,并根据实际情况进行适当的配置和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值