JavaEE实验
2021/2022(1)
实验9 spring-prj2
学生姓名 张坤
学生学号 201906061726
学生班级 软件工程1903
任课教师 韩珊珊
提交日期 2021年12月2日
计算机科学与技术学院
一、基础实验——Spring 容器中的依赖注入
实验内容及步骤
新建项目
导入maven包
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core --><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>5.3.8</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.8</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>5.3.8</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-expression</artifactId><version>5.3.8</version></dependency>
搭建spring框架
在spring-prj2 中新建cn.edu.zjut.bean 包,并在其中创建IItem 接口(代码略)及其实现类Item(代码片段如下);
public interface IItem {public double getUnitCost();}
@Datapublic class Item {private String itemID;private String title;private String description;private double cost;public Item(String itemID, String title,String description, double cost) {this.itemID = itemID;this.title = title;this.description = description;this.cost = cost;System.out.println("create Item.");}public double getUnitCost(){return cost;}}
在spring-prj2 中创建Spring 配置文件applicationContext.xml,并在其中使用构造器注入的方式配置Item 实例,具体代码如下
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans-4.0.xsd"><bean id="item1" class="cn.edu.zjut.bean.Item"><constructor-arg index="0" type="java.lang.String"><value>978-7-121-12345-1</value></constructor-arg><constructor-arg index="1" type="java.lang.String"><value>JAVAEE 技术实验指导教程</value></constructor-arg><constructor-arg index="2" type="java.lang.String"><value>WEB 程序设计知识回顾、轻量级JAVAEE 应用框架、企业级EJB 组件编程技术、JAVAEE 综合应用开发</value></constructor-arg><constructor-arg index="3" type="double"><value>19.95</value></constructor-arg></bean><bean id="item2" class="cn.edu.zjut.bean.Item"><constructor-arg index="0" type="java.lang.String"><value>978-7-121-12345-2</value></constructor-arg><constructor-arg index="1" type="java.lang.String"><value>JAVAEE 技术</value></constructor-arg><constructor-arg index="2" type="java.lang.String"><value>Struts 框架、Hibernate 框架、Spring 框架、会话Bean、实体Bean、消息驱动Bean</value></constructor-arg><constructor-arg index="3" type="double"><value>29.95</value></constructor-arg></bean></beans>
在spring-prj2 中新建cn.edu.zjut.app 包,并在其中创建测试类SpringEnvTest,对构造器注入进行测试,具体代码如下:
package cn.edu.zjut.app;import cn.edu.zjut.bean.Item;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class SpringEnvTest {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");Item item1 = (Item) ctx.getBean("item1");System.out.println(item1.getItemID());System.out.println(item1.getTitle());System.out.println(item1.getDescription());System.out.println(item1.getCost());Item item2 = (Item) ctx.getBean("item2");System.out.println(item2.getItemID());System.out.println(item2.getTitle());System.out.println(item2.getDescription());System.out.println(item2.getCost());}}
创建IItemOrder 接口
在spring-prj2 的cn.edu.zjut.bean 包中创建IItemOrder 接口及其实现类ItemOrder(代码片段如下);
package cn.edu.zjut.bean;/*** @Author: 张坤* @DateTime: 2021/11/24 14:05* @Description: 该类用于 TODO*/public interface IItemOrder {public void incrementNumItems();public void cancelOrder();public double getTotalCost();}
@Datapublic class ItemOrder implements IItemOrder{private Item item;private int numItems;public double getUnitCost(){return 11.1;}@Overridepublic void incrementNumItems() {setNumItems(getNumItems() + 1);}@Overridepublic void cancelOrder() {setNumItems(0);}@Overridepublic double getTotalCost() {return (getNumItems() * item.getUnitCost());}}@Datapublic class ItemOrder implements IItemOrder{private IItem item;private int numItems;public double getUnitCost(){return 11.1;}public void incrementNumItems() {setNumItems(getNumItems() + 1);}public void cancelOrder() {setNumItems(0);}public double getTotalCost() {return (getNumItems() * item.getUnitCost());}}
修改Spring 配置文件applicationContext.xml,在其中使用设置注入的方式增加ItemOrder 实例的配置,代码片段如下:
<bean id="itemorder1" class="cn.edu.zjut.bean.ItemOrder"><property name="numItems"> <value>1</value> </property><property name="item"> <ref bean="item1"/> </property></bean><bean id="itemorder2" class="cn.edu.zjut.bean.ItemOrder"><property name="numItems"> <value>2</value> </property><property name="item"> <ref bean="item2"/> </property></bean>
查看输出如下:
public class SpringEnvTest {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");ItemOrder itemorder1 = (ItemOrder)ctx.getBean("itemorder1");System.out.println("书名:" + (itemorder1).getItem().getTitle());System.out.println("数量:" + (itemorder1).getNumItems());ItemOrder itemorder2 = (ItemOrder)ctx.getBean("itemorder2");System.out.println("书名:" + (itemorder2).getItem().getTitle());System.out.println("数量:" + (itemorder2).getNumItems());}}
二、提高实验——Spring 容器中的Bean
实验内容及步骤
添加作用域属性
修改Spring 配置文件applicationContext.xml,为Item 实例的配置添加作用域属性(scope),代码片段如下:
<bean id="item1" class="cn.edu.zjut.bean.Item" scope="singleton"><constructor-arg index="0" type="java.lang.String" ><value>978-7-121-12345-1</value></constructor-arg><constructor-arg index="1" type="java.lang.String"><value>JAVAEE 技术实验指导教程</value></constructor-arg><constructor-arg index="2" type="java.lang.String"><value>WEB 程序设计知识回顾、轻量级JAVAEE 应用框架、企业级EJB 组件编程技术、JAVAEE 综合应用开发</value></constructor-arg><constructor-arg index="3" type="double"><value>19.95</value></constructor-arg></bean><bean id="item2" class="cn.edu.zjut.bean.Item" scope="prototype"><constructor-arg index="0" type="java.lang.String"><value>978-7-121-12345-2</value></constructor-arg><constructor-arg index="1" type="java.lang.String"><value>JAVAEE 技术</value></constructor-arg><constructor-arg index="2" type="java.lang.String"><value>Struts 框架、Hibernate 框架、Spring 框架、会话Bean、实体Bean、消息驱动Bean</value></constructor-arg><constructor-arg index="3" type="double"><value>29.95</value></constructor-arg></bean>
修改测试类SpringEnvTest
修改测试类SpringEnvTest,对bean 的作用域进行测试,代码片段如下:
public class SpringEnvTest {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");System.out.println("getBean(item1)---1");IItem item11 = (IItem) ctx.getBean("item1");System.out.println("getBean(item1)---2");IItem item12 = (IItem) ctx.getBean("item1");System.out.println("getBean(item2)---1");IItem item21 = (IItem) ctx.getBean("item2");System.out.println("getBean(item2)---2");IItem item22 = (IItem) ctx.getBean("item2");}}
查看结果
运行测试类SpringEnvTest,观察控制台的输出,并记录运行结果;
修改ItemOrder
修改cn.edu.zjut.bean 包中的ItemOrder.java,在其构造方法及setters 方法中添加相应的输出,代码片段如下:
public class ItemOrder implements IItemOrder, InitializingBean {private Item item;private int numItems;public ItemOrder() {System.out.println("Spring 实例化ItemOrder...");}public void setItem(Item item) {System.out.println("Spring 注入item...");this.item = item;}public void setNumItems(int n) {System.out.println("Spring 注入numItems...");this.numItems = n;}public double getUnitCost(){return 11.1;}@Overridepublic void incrementNumItems() {setNumItems(getNumItems() + 1);}@Overridepublic void cancelOrder() {setNumItems(0);}@Overridepublic double getTotalCost() {return (getNumItems() * item.getUnitCost());}@Overridepublic void afterPropertiesSet() throws Exception {}}
修改测试类SpringEnvTest
修改测试类SpringEnvTest,对bean 的初始化方法进行测试,代码片段如下:
public class SpringEnvTest {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");System.out.println("getBean(item1)---1");IItemOrder itemorder1 = (IItemOrder)ctx.getBean("itemorder1");}}
查看结果
运行测试类SpringEnvTest,观察控制台的输出,并记录运行结果
实现InitializingBean 接口
修改cn.edu.zjut.bean 包中的ItemOrder.java,通过实现InitializingBean 接口的方式,添加bean 的依赖关系注入之后的行为,代码片段如下:
public class ItemOrder implements IItemOrder, InitializingBean {public void afterPropertiesSet() throws Exception {System.out.println("正在执行初始化方法afterPropertiesSet...");}}
init-method
修改cn.edu.zjut.bean 包中的ItemOrder.java,通过自定义方法,添加bean 的依赖关系注入之后的行为,代码片段如下:
public class ItemOrder implements IItemOrder, InitializingBean {...public void init() {System.out.println("正在执行初始化方法init...");}}
修改Spring 配置文件applicationContext.xml,通过使用init-method 属性的方式,为ItemOrder 实例添加bean 的依赖关系注入之后的行为,代码片段如下:
<bean id="itemorder1" class="cn.edu.zjut.bean.ItemOrder" init-method="init"><property name="numItems"> <value>1</value> </property><property name="item"> <ref bean="item1"/> </property></bean>
destroy-method
实现接口方式
修改cn.edu.zjut.bean 包中的ItemOrder.java,通过实现DisposableBean 接口的方式,添加bean 销毁之前的行为(代码略);
public class ItemOrder implements IItemOrder, InitializingBean , DisposableBean {@Overridepublic void destroy(){System.out.println("正在准备执行销毁方法destroy...");}}
手动关闭容器
public class SpringEnvTest {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");System.out.println("getBean(item1)---1");IItemOrder itemorder1 = (IItemOrder)ctx.getBean("itemorder1");((AbstractApplicationContext)ctx).registerShutdownHook();}}
修改xml配置方式
修改cn.edu.zjut.bean 包中的ItemOrder.java,通过自定义方法,添加bean销毁之前的行为;并修改Spring 配置文件applicationContext.xml,通过使用destroy-method 属性的方式,为ItemOrder 实例添加bean 销毁之前
的行为;
<bean id="itemorder1" class="cn.edu.zjut.bean.ItemOrder" init-method="init" destroy-method="destroy"><property name="numItems"> <value>1</value> </property><property name="item"> <ref bean="item1"/> </property></bean>
静态工厂
在工程spring-prj2 的cn.edu.zjut.bean 包中创建工厂类ItemOrderFactory.java,并在类中提供静态工厂方法返回ItemOrder 实例,具体代码如下:
public class ItemOrderFactory {public static ItemOrder createItemOrder() {System.out.println("调用静态工厂方法创建bean...");return new ItemOrder();}}
修改Spring 配置文件applicationContext.xml,使用factory-method 属性调用静态工厂方法,创建ItemOrder 实例,代码片段如下:
<bean id="itemorder2" class="cn.edu.zjut.bean.ItemOrderFactory"factory-method="createItemOrder"><property name="numItems"> <value>1</value> </property><property name="item"> <ref bean="item1"/> </property></bean>
实例工厂
修改工厂类ItemOrderFactory.java,将其中的静态工厂方法修改为实例工厂方法,具体代码如下:
public class ItemOrderFactory {public ItemOrder createItemOrder() {System.out.println("调用实例工厂方法创建bean...");return new ItemOrder();}}
修改Spring 配置文件applicationContext.xml,使用factory-method 属性和factory-bean 属性调用实例工厂方法,创建ItemOrder 实例,代码片段如下
<bean id="itemorderFactory"class="cn.edu.zjut.bean.ItemOrderFactory"/><bean id="itemorder2" class="cn.edu.zjut.bean.ItemOrder"factory-method="createItemOrder"factory-bean="itemorderFactory"><property name="numItems"> <value>1</value> </property><property name="item"> <ref bean="item1"/> </property></bean>
三、扩展实验——深入Spring 容器
实验内容及步骤
不同的实例创建方法
修改测试类SpringEnvTest,分别使用XmlBeanFactory 创建BeanFactory 实例,或使FileSystemXmlApplicationContext、ClassPathXmlApplicationContext 创建ApplicationContext 实例,代码片段如下:
public class SpringEnvTest {public static void main(String[] args) {FileSystemResource isr = newFileSystemResource("src/applicationContext.xml");XmlBeanFactory factory = new XmlBeanFactory(isr);IItemOrder itemorder3 = (IItemOrder)factory.getBean("itemorder3");}}
运行不了
public class SpringEnvTest {public static void main(String[] args) {ClassPathResource res = newClassPathResource("applicationContext.xml");XmlBeanFactory factory = new XmlBeanFactory(res);IItemOrder itemorder3 = (IItemOrder)factory.getBean("itemorder2");}}

public class SpringEnvTest {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");IItemOrder itemorder3 = (IItemOrder)ctx.getBean("itemorder2");}}

public class SpringEnvTest {public static void main(String[] args) {ApplicationContext ctx = new FileSystemXmlApplicationContext("applicationContext.xml");IItemOrder itemorder3 = (IItemOrder)ctx.getBean("itemorder2");}}
国际化
在spring-prj2 中新建cn.edu.zjut.local 包,并在其中创建简体中文的资源文件:message_zh_CN.properties,在其中输入“HelloWorld={0},现在是{1}” ,并对其进行转码,最终得到
HelloWorld={0},\u73b0\u5728\u662f{1}
在cn.edu.zjut.local 包中创建美式英语的资源文件:message_en_US.properties,具体代码如下:
HelloWorld={0},now is{1}
两个文件的位置均在resource下
修改Spring 配置文件applicationContext.xml,增加名为messageSource 的bean实例以完成国际化的配置,代码片段如下:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"><property name="basenames"><list><value>cn.edu.zjut.local.message</value><!-- 如果有多个资源文件,全部列在此处--></list></property></bean>
转码方式如下:
打开jdk目录下的bin,找到native2ascii.exe文件,双击执行
修改测试类SpringEnvTest,对ApplicationContext 对国际化的支持进行测试,代码片段如下:
修改测试类SpringEnvTest,将其中的“Locale.CHINA”替换成“Locale.US”,运行测试类SpringEnvTest,观察控制台的输出,并记录运行结果;
spring事件
导入maven包
<dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>4.3.12.RELEASE</version></dependency>
在spring-prj2 中新建cn.edu.zjut.event 包,并在其中创建Spring 容器事件类,并继承ApplicationEvent 类,具体代码如下:
@Datapublic class EmailEvent extends ApplicationEvent {private String address;private String text;public EmailEvent(Object source){super(source);}public EmailEvent(Object source, String address, String text){super(source);this.setAddress(address);this.setText(text);}}
在spring-prj2 中新建cn.edu.zjut.listener 包,并在其中创建Spring 容器事件的监听器类,并实现ApplicationListener 接口,具体代码如下:
class EmailNotifier implements ApplicationListener {@Overridepublic void onApplicationEvent(ApplicationEvent evt){if(evt instanceof EmailEvent){EmailEvent emailEvent = (EmailEvent)evt;System.out.println("需要发送邮件的接收地址" +emailEvent.getAddress());System.out.println("需要发送邮件的邮件正文" +emailEvent.getText());}else{System.out.println("容器本身的事件" + evt);}}}
修改Spring 配置文件applicationContext.xml,Spring 容器事件注册监听器,代码片段如下:
<bean class="cn.edu.zjut.listener.EmailNotifier"/>
修改测试类SpringEnvTest,调用ApplicationContext 的publishEvent 来触发事件,代码片段如下:
public class SpringEnvTest {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");EmailEvent ele = new EmailEvent("hello", "spring_test@zjut.edu.cn", "this is a test");ctx.publishEvent(ele);}}




