Spring 4.1.6(二)

本文详细介绍Spring框架的安装配置,包括Eclipse插件安装、依赖管理及首个HelloWorld示例。深入探讨Spring容器的工作原理,Bean的定义、作用域、生命周期及依赖注入等关键概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

经过上一节,对spring的介绍,相信读者,对spring,有了大致的了解。大量篇幅的文字,看着就有点让人不耐烦,下面,我们就着手动起来。关于此系列的学习,依赖都是通过maven 去管理的。

Eclipse 安装spring插件

工欲善其事必先利其器,在eclipse 安装spring 插件将有利于我们的学习。

安装的时候,一定要注意eclipse 的版本,另外,spring 官网,一般都是最新的插件,在哪找历史的。

添加链接描述,可以参考这篇博客,安装的步骤,就不说,网上一大堆。

Helloworld Spring

首先先添加Spring 的依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.1.6.RELEASE</version>
</dependency>

定义一个POJO Java 对象类

public class HelloWord {
	private String message;

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}
}

定义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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
 <bean id="helloworld" class="test.HelloWord">
 <property name="message" value="hello spring"></property>//这里的name 是你的属性名,必须和POJO 对象的属性一致,value 是传入该属性的值
 </bean>
</beans>

对于Bean 的Id ,我们一定要保证它的唯一性。

创建的Beans.xml 的目录最好在maven工程下的src/main/java,这就是相当于传统Java 项目的src(src是目录的顶层),所以上面class,是从test开始的。还有注意的,Beans.xml 这个命名不是随意的

在main 函数里面测试:

	ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
		HelloWord h =  (HelloWord) context.getBean("helloworld");//这里的就是Beans.xml的配置的bean 的id,去获取该POJO 对象的。
	    System.out.println(h.getMessage());

ClassPathXmlApplicationContext 这个是负责加载配置文件,以及实例化所有的对象。

Spring 容器

容器负责创建对象,配置对象,管理对象的生命周期,从创建到消亡。这些对象,在Spring 中,被称之为Bean。配置Bean 的元数据库,可以是在Xml、Java 注解或者Java 代码中。(比如上面的例子,就是在Xml)。

下面是容器工作图:

在这里插入图片描述

Spring 容器类型

分两种:

  1. Spring BeanFactory Container

最简单的容器

  1. Spring ApplicationContext Container

这个容器,比上面的更高级,对于企业级应用,推荐使用这个。它的功能包含上面容器所有的。

Bean 定义

对象在Spring 容器中管理,从称之为Bean。Bean 一个对象,但是该对象是被实例化了,组装属性的。这些Bean 被创通过你在配置的元数据,去创建。

Bean 的定义,被称之为配置元数据,你配置这些数据,去让容器知道:

  1. 怎么去创建Bean
  2. Bean 的生命周期
  3. Bean 的依赖

Bean 的元数据配置是通过下面一系列的方法:

propertyDescription
class这个属性是必须的,指定Bean 的class
name这个属性是区分Bean 的,也是通过该属性获取Bean 对象,所以必须保证唯一性
scope指明Bean 的作用域
constructor-arg被用来指定依赖,后面有细讲
properties被用来指定依赖,后面有细讲
autowiring mode被用来指定依赖,后面有细讲
lazy-initialization mode懒加载,告诉容器创建Bean 实例,不是在开始,而是在第一次请求
initialization method初始化方法,所有的属性都由容器创建好了,回调的方法
destruction method销毁方法,所有的属性都由容器创建好了,回调的方法
Bean 元数据配置方式
  1. 基于Xml
  2. 基于注解
  3. 基于Java 代码
Bean 作用域
ScopeDescription
singleton(单例)该Bean作用域是整个容器, 只有一个Bean 实例
prototype(原型)该Bean作用域是,一个Bean可以有多个实例
request这将bean定义范围限定为HTTP请求。 在Web应用中,为每个请求创建一个bean实例。
session这将bean定义范围限定为session。 在Web应用中,为每个会话创建一个bean实例
Singleton

将上述Hello world 代码,main 中的代码,做如下的修改:

ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
		HelloWord h =  (HelloWord) context.getBean("helloworld");
		h.setMessage("i am new Spring");
	    System.out.println(h.getMessage());
		HelloWord h1 =  (HelloWord) context.getBean("helloworld");
	    System.out.println(h1.getMessage());

这里句不需要修改Beans.xml,因为Bean 默认就是这种作用域。

执行之后,你会发现两次打印的一致。实际上,采用这种模式的作用域,容器将把第一次实例的对象,放到缓存中,之后所有的请求,都是在缓存中拿,而不是重新去创建新的实例。

prototype

这种作用域,容器会为每一个Bean 创建新的实例。

基于上面的例子,我们修改Beans.xml:

 <bean id="helloworld" class="test.HelloWord" scope="prototype">

同样运行,这次,就一样的结果。说明每一个获取的Bean 实例,是不同的。

Bean 生命周期

当一个Bean 需要使用的时候,它通过容器去创建,当不需要的,从容器上移除。

public class ExampleBean {
	public void init() {
		System.out.println("bean start init");
	}
	public void destorty() {
		System.out.println("bean is destory");
	}
}
 <bean id="examplebean" class="test.ExampleBean" init-method="init" destroy-method="destorty"></bean>//这里填写对应的init 的destory 方法名,这个你保持和Bean 的方法一致即可。
 

还可以实现InitializingBean or DisposableBean 接口,实现Bean 的初始化和销毁,但是不建议,它会直接要你重写方法民,灵活性不行。

当如果多个Bean 里面都有这么一样的初始化、销毁的方法,可以可以直接在Beans 标签中,通过配置default-init-method and default-destroy-method 来减少重复性的设置。

如果上述你是web 应用,那么关闭服务器,就可以发现执行了destory 方法,init 方法不用说,创建的时候直接执行。也可以通过AbstractApplicationContext 的registerShutdownHook 去模拟容器的关闭。

AbstractApplicationContext  context = new ClassPathXmlApplicationContext("Beans.xml");
		ExampleBean eb = (ExampleBean) context.getBean("examplebean");
		context.registerShutdownHook();
BeanPostProcessor

如果我们需要在Spring容器完成Bean的实例化、配置和其他的初始化前后添加一些自己的逻辑处理,我们就可以定义一个或者多个BeanPostProcessor接口的实现,然后注册到容器中。

实例化Bean 的流程:

在这里插入图片描述

public class InitHelloWorld implements BeanPostProcessor {
         //Bean 初始化前
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("before init bean "+beanName);
		return bean;//这个地方在创建的时候,一定要注意就是返回bean 对象,否则会引起异常。
	}
	//Bean 初始化后
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("after init bean "+beanName);

		return bean;
	}

}
 <bean class="test.InitHelloWorld"></bean>//这个Bean 是没有id的,你不需要管他

ApplicationContext 会自动检测到所有实现该接口的Bean,并自动注册到容器中,所以,你还是要在Beans.xml中定义。

随便获取一个之前配置的Bean,会发现执行上面两个方法,在bean 初始化前后。

Bean 的继承

一个子类的Bean可以继承父类的Bean,可以重新相关的属性,以及添加自己需要的。

原先的HelloWorld 类不动,在编写一个子类:

public class SubHelloWorld {
	private String message;
	private String sonmessage;
	//相应的set、get方法省略,自行补充

}

这里有一点需要注意:尽管是继承,这里必须要重新定义父类的属性,否则尽管下面设置继承关系,一样没办法设置父类的属性,并且这个父类属性必须要和父类设置一样。

注意这里虽然是继承关系,但是不需要像Java 一样通过extends ,继承的关系,在下面Bean配置的标签parent 来体现:

<bean id="helloworld" class="test.HelloWord" scope="prototype">
 <property   name="message" value="hello spring" ></property>
 </bean>
 <bean id="subhelloworld" class="test.SubHelloWorld"  parent="helloworld">//parent 后面是跟的是父类Bean 的id
 <property name="sonmessage" value="i am son hello world"></property>//在这我们也可以设置父类的message 属性,修改为子类自己特有的,也可以不设置,就是父类的。
 
 </bean>

注意:一定你指定继承关系,如果直接获取子类的Bean,是可以获取父类的属性,无需多此一举,在get父类的Bean。

Bean 模板

在Java se 中,我们都知道可以定义一个抽象类加上继承,去实现一个公用的模板类,在Spring 也一样。

在上述代码,修改helloworld,将其定义成抽象的。

 <bean id="helloworld" class="test.HelloWord" abstract="true"></bean>

这样父类可以定义一些属性,子类可以直接用,或者重新赋值,子类还是要定义父类的属性(一模一样)。将父类定义成抽象的好处,父类就是一个纯洁的Bean 定义模板。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值