之前一直活在c/c++的世界里,最近来公司实习,项目上需要使用java spring的框架,本篇文章着重在于对spring框架进行最简单的配置和使用。
1.为何要引入spring
// 1. 实体类
class User{
}
//2. dao
class UserDao{
.. 访问db
}
//3. service
class UserService{
UserDao userDao = new UserDao();
}
//4. action
class UserAction{
UserService userService = new UserService();
..
拿到数据或结果
}
用户访问:
/user.action ----> Tomcat (服务器创建Action、Service、dao
思考:
- 对象创建创建能否写死?
- 对象创建细节
对象数量
action 多个 【维护成员变量】
service 一个 【不需要维护公共变量】
dao 一个 【不需要维护公共变量】
创建时间
action 访问时候创建
service 启动时候创建
dao 启动时候创建 - 对象的依赖关系
action 依赖 service
service依赖 dao
=======================================================
总结:
spring就是解决上面的问题的!
简单来说,就是处理对象的创建的、以及对象的依赖关系!
2.专业术语了解
组件/框架设计
- 侵入式设计:引入了框架,对现有的类的结构有影响;即需要实现或继承某些特定类。(例如:structs)
- 非侵入式设计:引入了框架,对现有的类结构没有影响。(例如:Hibernate框架 / Spring框架)
- 控制反转:Inversion on Control , 控制反转 IOC。对象的创建交给外部容器完成,这个就做控制反转。
class UserAction{
//需要什么,就创建什么,“控制正转”
IUserService userService = new UserService();
}
class UserAction{
private IUserService userService;
//对象的创建交给别人,叫控制反转 [依赖注入]
public IUserService setUserService(IUserService userService){
this.userService = userService;
}
}
- 依赖注入:处理对象的依赖关系
区别:
控制反转(IOC), 解决对象创建的问题 【对象创建交给别人】。
依赖注入,在创建完对象后, 对象的关系的处理就是依赖注入 。【通过set方法依赖注入】 - AOP:面向切面编程。切面,简单来说来可以理解为一个类,由很多重复代码形成的类。切面举例:事务、日志、权限;
3.Spring框架
3.1.概述
Spring框架,可以解决对象创建以及对象之间依赖关系的一种框架。且可以和其他框架一起使用;Spring与Struts, Spring与hibernate(起到整合(粘合)作用的一个框架)。
Spring提供了一站式解决方案:
Spring Core是spring的核心功能: IOC(控制反转)容器, 解决对象创建及依赖关系
Spring Web是Spring对web模块的支持。可以与struts整合,让struts的action创建交给spring。spring mvc模式。
Spring DAO Spring 对jdbc操作的支持 【JdbcTemplate模板工具类】
Spring ORM spring对orm的支持: 既可以与hibernate整合,【session】也可以使用spring的对hibernate操作的封装
Spring AOP 切面编程
SpringEE spring 对javaEE其他模块的支持
3.2.开发流程
3.2.1.源码, jar文件:spring-framework-3.2.5.RELEASE
在3.0以上的版本中,源码中只有spring的核心功能包。
在3.0以下的版本,源码有spring种相关的所有包。【spring功能包 + 依赖包】
commons-logging-1.1.3.jar 日志
spring-beans-3.2.5.RELEASE.jar bean节点
spring-context-3.2.5.RELEASE.jar spring上下文节点
spring-core-3.2.5.RELEASE.jar spring核心功能
spring-expression-3.2.5.RELEASE.jar spring表达式相关表
以上是必须引入的5个jar文件,在项目中可以用户库管理!
3.2.2.核心配置文件: applicationContext.xml
Spring配置文件:applicationContext.xml 或者叫做bean.xml
xml文件书写约束:
3.2.3.得到对象
package cn.itcast.a_hello;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class App1_get_ioc {
// 1. 通过工厂类得到IOC容器创建的对象
@Test
public void testIOC() throws Exception {
// 创建对象
// User user = new User();
// 现在,把对象的创建交给spring的IOC容器
Resource resource = new ClassPathResource("cn/itcast/a_hello/applicationContext.xml");
// 创建容器对象(Bean的工厂), IOC容器 = 工厂类 + applicationContext.xml
BeanFactory factory = new XmlBeanFactory(resource);
// 得到容器创建的对象
User user = (User) factory.getBean("user");
System.out.println(user.getId());
}
//2. (方便)直接得到IOC容器对象
@Test
public void testAc() throws Exception {
// 得到IOC容器对象
ApplicationContext ac = new ClassPathXmlApplicationContext("cn/itcast/a_hello/applicationContext.xml");
// 从容器中获取bean
User user = (User) ac.getBean("user");
System.out.println(user);
}
}
3.2.3.bean对象创建的细节
1) 对象创建: 单例/多例
* scope="singleton", 默认值, 即 默认是单例 【service/dao/工具类】
* scope="prototype", 多例; 【Action对象】
*
* 2) 什么时候创建?
* scope="prototype" 在用到对象的时候,才创建对象。
* scope="singleton" 在启动(容器初始化之前), 就已经创建了bean,且整个应用只有一个。
* 3)是否延迟创建
* lazy-init="false" 默认为false, 不延迟创建,即在启动时候就创建对象
* lazy-init="true" 延迟初始化, 在用到对象的时候才创建对象
* (只对单例有效)
* 4) 创建对象之后,初始化/销毁
* init-method="init_user" 【对应对象的init_user方法,在对象创建爱之后执行 】
* destroy-method="destroy_user" 【在调用容器对象的destriy方法时候执行,(容器用实现类)】
*/
@Test
**public** **void** testIOC() **throws** Exception {
// 得到IOC容器对象 【用实现类,因为要调用销毁的方法】
ClassPathXmlApplicationContext ac = **new** ClassPathXmlApplicationContext("cn/itcast/a_hello/applicationContext.xml");
System.*out*.println("-----容器创建-----");
// 从容器中获取bean
User user1 = (User) ac.getBean("user");
User user2 = (User) ac.getBean("user");
System.*out*.println(user1);
System.*out*.println(user2);
// 销毁容器对象
ac.destroy();
}
User.java
package cn.itcast.a_hello;
public class User {
private int id;
private String name;
public User() {
super();
System.out.println("------User对象创建------");
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void init_user() {
System.out.println("创建对象之后,初始化");
}
public void destroy_user() {
System.out.println("IOC容器销毁,user对象回收!");
}
}
3.2.4.SpringIOC容器
SpringIOS容器,是spring的核心内容。
作用:创建对象&处理对象的依赖关系。
容器创建对象:
- 调用无参数构造器
- 带参数的构造器
- 工厂创建对象(工厂类的静态方法创建对象,工厂类的非静态方法创建对象
3.3.对象依赖关系
Spring中,如何给对象的属性赋值?【DI,依赖注入,根据自己的依赖关系,去写相关的bean.xml文件】
- 通过构造函数
- 通过set方法给属性注入值(推荐使用,还有一种是内部bean的形式,当只有一个action的时候,可以使用)
这里面包含了 ,Dao,service ,action之间的数据流程关系
会直接调用set方法
和上面同理
- 内部bean的用法
- p名称空间(给对象属性注入值,也可以使用p名称空间给对象的属性注入值,在spring3.0以上的版本才支持)
- 自动装配(了解,其实各个对象都是放在容器之中。)
自动去IOC容器中找与属性名同名的引用的对象,并自动注入
也可以定义到全局, 这样就不用每个bean节点都去写autowire=”byName”
根据名称自动装配(全局)
根据类型自动装配:autowire="byType"
必须确保改类型在IOC容器中只有一个对象;否则报错。