Servlet/JSP Ajax/jQuery
Web 前端、Web界面编程
对象的管理
创建和销毁
Spring
IOC AOP
Spring最核心的功能:管理对象
管理对象的生存周期,和对象的关系
概念:Java Bean(POJO)实现如下规则的Java对象
1 必须有包(package)
2 必须有无参数构造器
3 实现序列化接口
4 有getXXX setXXX方法定义的Bean属性XXX
String getName()
void setName(String n)
定义了Bean 属性 name 与 对象的属性不同!
比如:EL表达式可以访问Bean属性!
5 toString
equals hashCode 有ID 基本都重写
简而言之:有一定约定的Java对象!
Spring 管理的Java Bean对象,访问Bean属性
applicationContext.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:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/tx/spring-jms-3.2.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/tx/spring-lang-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/tx/spring-mvc-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/tx/spring-util-3.2.xsd">
<!-- 告诉Spring在运行期间,创建
GregorianCalendar类型的对象,
编号为 calObj1 -->
<bean id="calObj1"
class="java.util.GregorianCalendar"/>
<bean id="list"
class="java.util.ArrayList"/>
<!-- Spring使用静态工厂方法创建Bean对象
Spring 会调用Calendar类的getInstance方法
创建Bean对象,Bean的类型是返回值类型-->
<bean id="calObj2"
class="java.util.Calendar"
factory-method="getInstance"/>
<!-- 声明作为工厂的Bean对象 -->
<bean id="calObj3"
class="java.util.GregorianCalendar"/>
<!-- 利用对象calObj3作为工厂生产Bean -->
<bean id="dateObj"
factory-bean="calObj3"
factory-method="getTime"/>
<!-- 原型的对象,每次getBean都创建新对象 -->
<bean id="dateObj2"
class="java.util.Date"
scope="prototype"/>
<!-- 测试bean对象生存周期管理 -->
<bean id="examObj1"
class="spring.day01.ExampleBean"
init-method="init"
destroy-method="destroy"/>
<!-- 原型的对象destroy-method无效!-->
<bean id="examObj2" scope="prototype"
class="spring.day01.ExampleBean"
init-method="init"
destroy-method="destroy"/>
<!-- 典型的原型Bean应用 -->
<bean id="code" scope="prototype"
class="spring.day01.Code"
init-method="init"/>
<!-- Bean注入,解决对象的关系管理 -->
<bean id="e" scope="prototype"
class="spring.day01.Egg" />
<bean id="food" scope="prototype"
class="spring.day01.TomatoWithEgg">
<!-- 调用Bean属性设置方法setEgg()
将id为egg的Bean对象注入(DI/IOC)到
西红柿炒蛋(food)中 -->
<property name="egg" ref="e"/>
</bean>
</beans>
package spring.day01;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Random;
import javax.imageio.ImageIO;
/**
* 将验证码管理封装为一个Bean
*
*/
public class Code implements Serializable {
String code;//null
BufferedImage image;
/**
* 验证 用户输入的号码,与当前对象的code
* 是否一致,一致返回true,否则false
*/
public boolean verify(String input){
return code.equalsIgnoreCase(input);
}
public void init(){
//初始化 code
//根据验证码 生成图片
code = initCode();
image = initImage(code);
}
private BufferedImage initImage(
String code) {
BufferedImage img =
new BufferedImage(80,30,
BufferedImage.TYPE_3BYTE_BGR);
Graphics g = img.createGraphics();
g.setColor(new Color(0xffffff));
g.fillRect(0, 0, 80, 30);
g.setColor(new Color(0xEDBE00));
g.drawString(code, 10, 25);
Random r = new Random();
for(int i=0 ; i<5; i++){
int c = r.nextInt(0xffffff);
g.setColor(new Color(c));
g.drawLine(r.nextInt(80),r.nextInt(30),
r.nextInt(80),r.nextInt(30));
}
return img;
}
private String initCode() {
String str = "abcdefghABCDEF345678";
char[] c = new char[4];
Random r = new Random();
c[0]=str.charAt(r.nextInt(str.length()));
c[1]=str.charAt(r.nextInt(str.length()));
c[2]=str.charAt(r.nextInt(str.length()));
c[3]=str.charAt(r.nextInt(str.length()));
return new String(c);
}
//将当前验证码图片保存的流中
public void save(OutputStream out)
throws IOException{
ImageIO.write(this.image, "png", out);
}
}
package spring.day01;
public class Egg {
public String toString(){
return "鸡蛋";
}
}
package spring.day01;
import java.io.Serializable;
public class ExampleBean
implements Serializable {
String n;
public ExampleBean(){
n = "Tom";
System.out.println("Call ExampleBean()");
}
public String getName(){
return n;
}
public void setName(String n){
this.n = n;
}
public String toString(){
return "n="+n;
}
public void init(){
System.out.println("call init()");
}
public void destroy(){
System.out.println("call destroy()");
}
}
package spring.day01;
import java.util.Calendar;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
//applicationContext.xml 在 src 文件夹
String cfg = "applicationContext.xml";
//创建Spring容器(请管家,提供菜单)
ApplicationContext ctx =
new ClassPathXmlApplicationContext(cfg);
//从Spring容器中获得创建好的 calObj1 对象
Calendar cal1 =
(Calendar)ctx.getBean("calObj1");
System.out.println(cal1);//测试是否有对象
List list =
ctx.getBean("list",List.class);
System.out.println(list);
}
}
package spring.day01;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 测试案例
*/
public class TestCase {
//@Test //注解
public void testGetBean(){
String cfg = "applicationContext.xml";
ApplicationContext ctx =
new ClassPathXmlApplicationContext(cfg);
Calendar cal = ctx.getBean(
"calObj1", Calendar.class);
System.out.println(cal);
}
//修改 TestCase 增加测试方法
//@Test//测试Spring利用静态工厂方法创建Bean对象
public void testStaticFactory(){
String cfg = "applicationContext.xml";
ApplicationContext ctx =
new ClassPathXmlApplicationContext(cfg);
Calendar cal = ctx.getBean(
"calObj2", Calendar.class);
System.out.println(cal);
}
//@Test//实例工厂创建Bean实例
public void testBeanFactory(){
String cfg = "applicationContext.xml";
ApplicationContext ctx =
new ClassPathXmlApplicationContext(cfg);
Date date = ctx.getBean(
"dateObj", Date.class);
System.out.println(date);
}
//@Test//测试Spring默认管理对象是单例的
public void testSingleton(){
String cfg = "applicationContext.xml";
ApplicationContext ctx =
new ClassPathXmlApplicationContext(cfg);
Date d1 = ctx.getBean(
"dateObj", Date.class);
System.out.println(d1);
Date d2 = ctx.getBean(
"dateObj", Date.class);
System.out.println(d1==d2);//true
}
//@Test//生存周期的管理方法 init destroy
public void testLifeCircle(){
String cfg = "applicationContext.xml";
//ApplicationContext对象也称为Spring容器
ApplicationContext ctx =
new ClassPathXmlApplicationContext(cfg);
ExampleBean bean1 = ctx.getBean(
"examObj1",ExampleBean.class);
System.out.println(bean1);
ExampleBean bean2 = ctx.getBean(
"examObj2", ExampleBean.class);
System.out.println(bean2);
//AbstractApplicationContext 定义close()
AbstractApplicationContext c =
(AbstractApplicationContext)ctx;
c.close();//关闭Spring容器
}
//@Test
public void testCode()
throws IOException{
String cfg = "applicationContext.xml";
ApplicationContext ctx =
new ClassPathXmlApplicationContext(cfg);
Code c1=ctx.getBean("code",Code.class);
Code c2=ctx.getBean("code", Code.class);
System.out.println(c1.code);
System.out.println(c2.code);
c1.save(new FileOutputStream("c1.png"));
c2.save(new FileOutputStream("c2.png"));
}
@Test
public void testIOC()
throws IOException{
String cfg = "applicationContext.xml";
ApplicationContext ctx =
new ClassPathXmlApplicationContext(cfg);
TomatoWithEgg food =
ctx.getBean("food", TomatoWithEgg.class);
System.out.println(food);
}
}
package spring.day01;
public class TomatoWithEgg {
Egg egg;
//Tomato t;
public Egg getEgg() {
return egg;
}
public void setEgg(Egg egg) {
this.egg = egg;
}
public String toString(){
return "西红柿炒"+egg;
}
}
(2)————–
Spring
1 Java Bean 具有约束的Java 类
包
序列化
无参数构造器
Bean属性-> getXXX setXXX
一般情况下,所有类都是Java Bean规则
Spring 两大核心功能:IOC AOP
IOC:管理对象和对象的关系
1 创建Bean实例管理Bean的生存周期
Bean的实例化:创建对象,由Spring容量管理
Spring支持3种Bean的实例化:
构造器
静态工厂方法
实例(对象)工厂的工厂方法
对象的作用域:单例和原型
Spring默认的是单例管理
Spring在啥时候创建对象:
单例对象在容器启动时候,可以利用参数修改
原型对象在 需要的时候
对象生存周期管理方法
对象的状态==数据==对象的属性
Spring 提供了注入DI/IOC 功能,解决维护对象的
关系。解决了耦合性问题
紧耦合 与 松耦合
紧耦合:代码写死了,对象关系不能改变
松耦合:对象的关系,可以后期更改,无需变更编码
IOC/DI 最终解决了对象的耦合性
Spring 支持多种数据类型的注入
注入类型:
基本类型数据注入
引用类型注入:
集合注入
Spring 支持两种方式:
Bean属性注入(set方法注入)
构造器参数注入(调用有参数构造器注入)
自动装配,采用默认规则,不直观,容易晕倒
byName 规则
Spring会自动的将 Bean属性与Bean的ID按名字匹配
如果匹配上,就自动调用 set方法进行注入
class Food{
Egg egg;
//Food 有Bean属性 egg
public void setEgg(Egg e){
egg = e;
}
}
<bean id="egg" class="Egg" />
<bean id="food" class="Food" autowire="byName"/>
byType 规则
Spring 会在容器中查找与Bean属性类型一致的Bean
对象类型,如果类型(class)一致,就调用set方法注入属性
如果有同类型的Bean对象,注入失败抛异常!
class Food{
Egg egg;
//Food 有Bean属性 egg
public void setEgg(Egg e){
egg = e;
}
}
<bean id="e" class="Egg" />
<bean id="food" class="Food" autowire="byType"/>
Spring 基本类型注入(基本类和字符串)
表达式注入
用于读取一个Bean的属性,注入给另外一个Bean
class MessageBean{
String msg = "Hello";
public String getMsg(){
return msg;
}
public void setMsg(String msg){
this.msg = msg;
}
}
<bean id="msgBean" class="MessageBean"/>
//两种读取方式#{msgBean.msg}或#{msgBean['msg']}
<bean id="demoBean" class="0">
<property name="error"
value="#{msgBean.msg}"/>
</bean>
读取list/数组: #{nameList[0]}
读取map:#{map['key']} #{map.key}
读取properties:#{props['key']} #{props.key}
案例:从properties 中读取jdbc配置信息,
注入到dataSource Bean中
利用Spring 的表达注入实现
1 有配置文件 db.properties 在src文件(classpath)
driver=oracle.jdbc.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:orcl
user=openlab
pwd=open123
2 利用 <util:properties> 读取为Bean
<util:properties id="jdbc"
location="classpath:db.properties">
3 表达式注入到 dataSource
<bean id="dataSource"
class="JdbcDataSource">
<property name="driver"
value="#{jdbc.driver}"/>
//...
</bean>
Spring
1 Java Bean 具有约束的Java 类
包
序列化
无参数构造器
Bean属性-> getXXX setXXX
一般情况下,所有类都是Java Bean规则
Spring 两大核心功能:IOC AOP
IOC:管理对象和对象的关系
1 创建Bean实例管理Bean的生存周期
Bean的实例化:创建对象,由Spring容量管理
Spring支持3种Bean的实例化:
构造器
静态工厂方法
实例(对象)工厂的工厂方法
对象的作用域:单例和原型
Spring默认的是单例管理
Spring在啥时候创建对象:
单例对象在容器启动时候,可以利用参数修改
原型对象在 需要的时候
对象生存周期管理方法
对象的状态==数据==对象的属性
Spring 提供了注入DI/IOC 功能,解决维护对象的
关系。解决了耦合性问题
紧耦合 与 松耦合
紧耦合:代码写死了,对象关系不能改变
松耦合:对象的关系,可以后期更改,无需变更编码
IOC/DI 最终解决了对象的耦合性
Spring 支持多种数据类型的注入
注入类型:
基本类型数据注入
引用类型注入:
集合注入
Spring 支持两种方式:
Bean属性注入(set方法注入)
构造器参数注入(调用有参数构造器注入)
自动装配,采用默认规则,不直观,容易晕倒
byName 规则
Spring会自动的将 Bean属性与Bean的ID按名字匹配
如果匹配上,就自动调用 set方法进行注入
class Food{
Egg egg;
//Food 有Bean属性 egg
public void setEgg(Egg e){
egg = e;
}
}
<bean id="egg" class="Egg" />
<bean id="food" class="Food" autowire="byName"/>
byType 规则
Spring 会在容器中查找与Bean属性类型一致的Bean
对象类型,如果类型(class)一致,就调用set方法注入属性
如果有同类型的Bean对象,注入失败抛异常!
class Food{
Egg egg;
//Food 有Bean属性 egg
public void setEgg(Egg e){
egg = e;
}
}
<bean id="e" class="Egg" />
<bean id="food" class="Food" autowire="byType"/>
Spring 基本类型注入(基本类和字符串)
Spring
Java Bean
Spring 核心功能有两个 IOC AOP
IOC/DI 控制反转/依赖注入
AOP 面向方面编程
根本上是管理 Bean对象和对象的关系
IOC
蛋炒饭 与 鸡蛋\米饭
蛋炒饭
|-- 鸡蛋
|-- 米饭
Spring IOC/DI
控制反转/依赖注入: 解决对象的依赖关系
是管理对象, 将对象按照配置文件进行注入
解决耦合性问题: 解耦
对象事物的关联关系
从需要对象时候 创建/获得
到需要对象时候, 由容器自动注入
也就是将创建对象的控制权, 由程序变为, 由容器
创建,并且注入: 称为控制反转
回顾 EL 表达式
<?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:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:jms="http://www.springframework.org/schema/jms"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/tx/spring-jms-3.2.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/tx/spring-lang-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/tx/spring-mvc-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/tx/spring-util-3.2.xsd">
<bean id="dataSource"
class="com.company.dao.JdbcDataSource">
<!-- Bean属性注入 setDriver -->
<property name="driver"
value="oracle.jdbc.OracleDriver"/>
<property name="url"
value="jdbc:oracle:thin:@192.168.160.252:1521:orcl"/>
<property name="user"
value="openlab"/>
<property name="pwd"
value="open123"/>
</bean>
<!-- 构造器注入 -->
<bean id="demoBean"
class="com.company.test.DemoBean">
<!-- Spring调用有参数构造器创建对象 -->
<constructor-arg index="0"
value="Tom"/>
<constructor-arg index="1"
value="500"/>
</bean>
<!-- 自动属性注入:
自动找到id为dataSource的Bean注入到
Bean属性:dataSource中(setDataSource方法) -->
<bean id="userDao" autowire="byName"
class="com.company.dao.OracleUserDao"/>
<!-- 基本属性注入 -->
<bean id="bean"
class="com.company.test.ExampleBean">
<property name="price"
value="55.9"/>
<property name="time">
<value>0</value>
</property>
<property name="name">
<value>Andy</value>
</property>
</bean>
</beans>
(3)
Spring
为什么要注入(DI/IOC)
因为对象是有关系的!
在软件运行期间,对象之间根据业务需要有关联关系
引用变量,在运行期间动态绑定到对象
进而解决的对象的耦合性
Spring的注入
1 支持两种方式注入
A 构造器参数注入(不常用)
B set方法输入(Bean属性注入)
2 Spring支持各种类型数据的注入
A 基本类型数据(含String)
B 对象(Bean)的注入
1) 引用方式
<property name="egg" ref="egg"/>
2) 匿名Bean,没有ID的Bean (不常用)
<bean id="food" class="Food">
<property name="egg" >
<bean class="Egg"/>
</property>
</bean>
C 集合的注入 list set map properties
1) 集合中元素可以是基本类型
2) 集合中元素可以是Bean对象
3) 引用方式注入集合
使用命名空间 util:
D Spring 表达式注入
1) 从Bean对象中读取数据,注入到其他Bean
2) 支持从 Bean属性读取,List集合读取
Map集合,Properties集合
3) 语法与 JSP EL 表达式相同
常见用途:读取properties文件
软件的结构与Spring
软件一般都采用“经典”的“设计模式”
软件经典结构:3层架构
表现层:就是软件的界面,用来呈现数据,与用户交互
业务层: 封装的了软件的核心功能(业务逻辑功能)
数据层: 提供业务实体的 CRUD(增删改查),也
叫持久化层
Spring 可以将软件的各个层次模块进行集成
管理。
表现层:Spring MVC 登录框
业务层: UserService
User login(String name, String pwd)
数据层:UserDao (OracleUserDao MySqlUserDao)
User findByName(String name)
JdbcDataSource 管理数据库连接
db.properties
applicationContext.xml
Spring
为什么要注入(DI/IOC)
因为对象是有关系的!
在软件运行期间,对象之间根据业务需要有关联关系
引用变量,在运行期间动态绑定到对象
进而解决的对象的耦合性
Spring的注入
1 支持两种方式注入
A 构造器参数注入(不常用)
B set方法输入(Bean属性注入)
2 Spring支持各种类型数据的注入
A 基本类型数据(含String)
B 对象(Bean)的注入
1) 引用方式
<property name="egg" ref="egg"/>
2) 匿名Bean,没有ID的Bean (不常用)
<bean id="food" class="Food">
<property name="egg" >
<bean class="Egg"/>
</property>
</bean>
C 集合的注入 list set map properties
1) 集合中元素可以是基本类型
2) 集合中元素可以是Bean对象
3) 引用方式注入集合
使用命名空间 util:
D Spring 表达式注入
1) 从Bean对象中读取数据,注入到其他Bean
2) 支持从 Bean属性读取,List集合读取
Map集合,Properties集合
3) 语法与 JSP EL 表达式相同
常见用途:读取properties文件
软件的结构与Spring
软件一般都采用“经典”的“设计模式”
软件经典结构:3层架构
表现层:就是软件的界面,用来呈现数据,与用户交互
业务层: 封装的了软件的核心功能(业务逻辑功能)
数据层: 提供业务实体的 CRUD(增删改查),也
叫持久化层
Spring 可以将软件的各个层次模块进行集成
管理。
表现层:Spring MVC 登录框
业务层: UserService
User login(String name, String pwd)
数据层:UserDao (OracleUserDao MySqlUserDao)
User findByName(String name)
JdbcDataSource 管理数据库连接
db.properties
applicationContext.xml
注解方式的默认Bean ID命名规则
类名DemoBean 注册Bean ID 为 demoBean
类名Bean 注册Bean ID 为 bean
类名SQLBean 注册Bean ID 为 SQLBean 不建议使用!
类名OracleUserDao 注册Bean ID 为 oracleUserDao
另外命名(建议按照接口命名):
类名OracleUserDao @Component("userDao")
注册Bean ID 为 userDao
注入指定ID的Bean
假设 Egg @Component("e")
同时 <bean id="bigEgg" class="Egg"/>
class Food{
@Resource(name="e")
Egg egg;
}
利用注解管理 软件的组件
@Service
UserService{
@Resource
UserDao userDao;
}
@Repository("userDao")
OracleUserDao{
@Resource
JdbcDataSource dataSource;
}
@Component("dataSource")
JdbcDataSource{
String driver;
@Value("#{jdbc.url}")
String url;
String user;
String pwd;
@Value("#{jdbc.driver}")
public void setDriver(String driver){
//....
}
}
<util:properties id="jdbc" .../>