Spring框架入门教程

一、概述
  • Spring是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架。
  • Spring的核心是控制反转IOC和面向切面AOP。
  • Spring解决的是业务逻辑层和其他各层的松耦合问题。
  • Spring可以解决对象创建以及对象之间依赖关系的一种框架
  • Spring可以和其他框架一起使用。
二、Spring4示例
(待续)
三、组件/框架设计
  • 侵入式设计
引入了框架,对现有的类的结构有影响;即需要实现或继承某些特定类。
例如:Struts框架
  • 非侵入式设计
引入了框架,对现有的类结构没有影响。
例如:Hibernate框架 / Spring框架
四、 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方法时候执行,(容器用实现类)】
五、SpringIOC容器(spring核心内容)
1.作用:创建对象 和 处理对象的依赖关系
2.控制反转和依赖注入
Inversion on Control , 控制反转 IOC,对象的创建交给外部容器完成,这个就做控制反转.
dependency injection , 依赖注入,处理对象的依赖关系
区别:
控制反转, 解决对象创建的问题 【对象创建交给别人】
依赖注入, 在创建完对象后, 对象的关系的处理就是依赖注入 【通过set方法依赖注入】
3.创建对象的几种方式: 

 















4.获取对象的几种方式
方式1. 直接得到IOC容器对象(推荐) 
// 得到IOC容器对象
ApplicationContext ac = new ClassPathXmlApplicationContext("cn/itcast/a_hello/applicationContext.xml");
// 从容器中获取bean
User user = (User) ac.getBean("user");
配置文件中:

方式2. 通过工厂类得到IOC容器创建的对象
// 把对象的创建交给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");
5.对象依赖关系:
①注解方式(注解方式可以简化spring的IOC容器的配置)
使用注解步骤:
1)先引入context名称空间约束
xmlns:context="http://www.springframework.org/schema/context"
2)开启注解扫描

3)使用注解(通过注解的方式,把对象加入ioc容器)
  创建对象以及处理对象依赖关系,相关的注解:
@Component    指定把一个对象加入IOC容器
@Repository   作用同@Component; 在持久层使用
@Service      作用同@Component; 在业务逻辑层使用
@Controller   作用同@Component; 在控制层使用 
@Resource     属性注入
②Set方法注入值










③p名称空间注入属性值



④自动装配,自动去IOC容器中找与属性名同名的引用的对象,并自动注入


根据“名称”自动装配: userAction注入的属性,会去ioc容器中自动查找与属性同名的对象

或者:也可以定义到全局, 这样就不用每个bean节点都去写autowire=”byName”
default-autowire="byName">   根据名称自动装配(全局)
根据类型自动装配:autowire="byType"
6.Spring中给对象的属性赋值方式:
①通过构造函数
②通过set方法给属性注入值
③p名称空间
④自动装配(了解)
⑤注解
六、AOP编程
1.概述:aspect object programming 面向切面编程,让关注点代码与业务代码分离!
关注点:重复代码就叫做关注点;
切面:关注点形成的类,就叫切面(类)
面向切面编程:指对很多功能都有的重复的代码抽取,再在运行的时候网业务方法上动态植入“切面类代码”。
切入点:执行目标对象方法,动态植入切面代码。
可以通过切入点表达式,指定拦截哪些类的哪些方法;给指定的类在运行的时候植入切面类代码。
2.业务代码与关注点代码分离的好处:
-关注点代码写一次即可;
-开发者只需要关注核心业务;
-运行时期,执行核心业务代码时候动态植入关注点代码【代理】。
3.切面举例:事务、日志、权限;AOP可以进行权限校验,日志记录,性能监控,事务控制等。
4.注解方式实现AOP编程(推荐)
步骤:
1)先引入aop相关jar文件(aspectj  aop优秀组件)
spring-aop-3.2.5.RELEASE.jar  【spring3.2源码】
aopalliance.jar  【spring2.5源码/lib/aopalliance】
aspectjweaver.jar  【4spring2.5源码/lib/aspectj】或【aspectj-1.8.2\lib】
aspectjrt.jar  【spring2.5源码/lib/aspectj】或【aspectj-1.8.2\lib】
注意: 用到spring2.5版本的jar文件,如果用jdk1.7可能会有问题。
需要升级aspectj组件,即使用aspectj-1.8.2版本中提供jar文件提供。
2)bean.xml中引入aop名称空间和配置
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"


3)开启aop注解
4)使用注解
@Aspect 指定一个类为切面类
@Pointcut("execution(* cn.itcast.e_aop_anno.*.*(..))")  指定切入点表达式
@Before("pointCut_()") 前置通知: 目标方法之前执行
@After("pointCut_()") 后置通知:目标方法之后执行(始终执行)
@AfterReturning("pointCut_()") 返回后通知: 执行方法结束前执行(异常不执行)
@AfterThrowing("pointCut_()") 异常通知:  出现异常时候执行
@Around("pointCut_()") 环绕通知: 环绕目标方法执行
5.XML方式实现AOP编程(不推荐)
步骤:
1)先引入aop相关Maven依赖
2)bean.xml中引入aop名称空间
3)aop 配置
* 配置切面类 (重复执行代码形成的类)


* aop配置

















6.切入点表达式
对指定的"方法"进行拦截,从而给指定的方法所在的类生层代理对象.
七、代理模式
1.概述:代理(Proxy)是一种设计模式, 提供了对目标对象另外的访问方式;即通过代理访问目标对象。
  好处:可以在目标对象实现的基础上,增强额外的功能操作。(扩展目标对象的功能)。
  代理模式的关键点: 代理对象与目标对象
2.静态代理
1) 代理对象,要实现与目标对象一样的接口;
2)可以做到在不修改目标对象的功能前提下,对目标对象功能扩展。
3)缺点:
--》  因为代理对象,需要与目标对象实现一样的接口。所以会有很多代理类,类太多。
--》  一旦接口增加方法,目标对象与代理对象都要维护。
3.动态代理
1)代理对象,不需要实现接口;
2)代理对象的生成,是利用JDKAPI,动态的在内存中构建代理对象
3)动态代理,JDK代理,接口代理;
4)JDK中生成代理对象的API:
|-- Proxy
static Object newProxyInstance(
ClassLoader loader,       指定当前目标对象使用类加载器
Class[] interfaces,     目标对象实现的接口的类型
InvocationHandler h       事件处理器
5)代理对象不需要实现接口,但是目标对象一定要实现接口;否则不能用动态代理!
(class  $Proxy0  implements IuserDao)
③Cglib代理:也叫做子类代理。在内存中构建一个子类对象从而实现对目标对象功能的扩展。
 JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现接口的类,就可以使用CGLIB实现。 
 CGLIB是一个强大的高性能的代码生成包,它可以在运行期扩展Java类与实现Java接口。它广泛的被许多AOP的框架使用,例如Spring AOP和dynaop,为他们提供方法的interception(拦截)。 
 CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。
④Cglib子类代理:
1)需要引入cglib – jar文件, 但是spring的核心包中已经包括了cglib功能,所以直接引入spring-core-3.2.5.jar即可。
2)引入功能包后,就可以在内存中动态构建子类
3)代理的类不能为final, 否则报错。
4)目标对象的方法如果为final/static, 那么就不会被拦截,即不会执行目标对象额外的业务方法。
⑤总结:
在Spring的AOP编程中,如果加入容器的目标对象有实现接口,用JDK代理;如果目标对象没有实现接口,用Cglib代理;
八、Spring对jdbc的支持
使用步骤:
①引入Maven依赖

 org.springframework
 spring-tx
 4.2.5.RELEASE


 org.springframework
 spring-jdbc
 4.2.5.RELEASE

②代码中:
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void save() {
String sql = "insert into t_dept(deptName) values('test');";
jdbcTemplate.update(sql);
}
public Dept findById(int id) {
String sql = "select * from t_dept where deptId=?";
List list = jdbcTemplate.query(sql,new MyResult(), id);
return (list!=null && list.size()>0) ? list.get(0) : null;
}
class MyResult implements RowMapper{
@Override
public Dept mapRow(ResultSet rs, int index) throws SQLException {
Dept dept = new Dept();
dept.setDeptId(rs.getInt("deptId"));
dept.setDeptName(rs.getString("deptName"));
return dept;
}
}
③bean.xml配置中:



















九、声明式事务控制
1.概述:Spring提供了对事务控制的实现。用户如果想用Spring的声明式事务管理,只需要在配置文件中配置即可,不想使用时直接移除配置。这个实现了对事务控制的最大程度的解耦。
Spring声明式事务管理,核心实现就是基于Aop。
2.Spring声明式事务管理器类:
Jdbc技术:DataSourceTransactionManager
Hibernate技术:HibernateTransactionManager
3.步骤:
1) 引入spring-aop相关的Maven依赖
2) 引入aop名称空间  【XML配置方式需要引入】
3) 引入tx名称空间   【事务方式必须引入】
4) a.xml配置方式实现:
Spring声明式事务管理配置

















   
b.注解方式实现
Ⅰ.bean.xml中指定注解方式实现声明式事务管理以及应用的事务管理器类
Ⅱ.在需要添加事务控制的地方,写上: @Transactional
@Transactional注解:
1)应用事务的注解
2)定义到方法上: 当前方法应用spring的声明式事务
3)定义到类上:   当前类的所有的方法都应用Spring声明式事务管理;
4)定义到父类上: 当执行父类的方法时候应用事务。
4.事务属性
@Transactional(
readOnly = false,  // 读写事务
timeout = -1,       // 事务的超时时间不限制
noRollbackFor = ArithmeticException.class,  // 遇到数学异常不回滚
isolation = Isolation.DEFAULT,              // 事务的隔离级别,数据库的默认
propagation = Propagation.REQUIRED // 事务的传播行为
)
5.事务传播行为:
Propagation.REQUIRED
指定当前的方法必须在事务的环境下执行;
如果当前运行的方法,已经存在事务, 就会加入当前的事务;
Propagation.REQUIRED_NEW
指定当前的方法必须在事务的环境下执行;
如果当前运行的方法,已经存在事务:  事务会挂起; 会始终开启一个新的事务,执行完后;刚才挂起的事务才继续运行。
十、Spring的优点
①方便解耦,简化开发
Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理
②AOP编程的支持
Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
③声明式事务的支持
只需要通过配置就可以完成对事务的管理,而无需手动编程
④方便程序的测试
Spring对Junit4支持,可以通过注解方便的测试Spring程序
⑤方便集成各种优秀框架
Spring可以整合各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持
⑥降低JavaEE API的使用难度
Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低
十一、Spring提供了一站式解决方案
1. Spring Core  spring的核心功能:IOC容器, 解决对象创建及依赖关系
2. Spring Web   Spring对web模块的支持。
3. Spring DAO   Spring 对jdbc操作的支持  【JdbcTemplate模板工具类】
4. Spring ORM   spring对orm的支持: 
5. Spring AOP   切面编程
6. Spring EE    spring 对javaEE其他模块的支持

你可能感兴趣的:(JavaWeb,Spring)