Spring 框架之IOC、AOP
spring概念
spring是项目中对象的容器.用来管理项目中的所有对象.
- 创建对象,并维护对象间的关系AOP
- 整合代理技术,实现AOP思想
- spring可以整合几乎任何第三方框架,作为项目中的粘合剂.
IOC&DI概念
- IOC:反转控制,创建对象的方式被反转,从我们自己创建变为程序创建.
- DI:依赖注入,是技术,可以将依赖属性注入到对象.构造注入|set方法注入.IOC的实现需要依赖DI技术.
BeanFactory&ApplicationContext
- BeanFactory接口
- BeanFactory是spring框架初代接口.
- BeanFactory是ApplicationContext父接口.
- BeanFactory是获得对象时才创建对象.
- ApplicationContext接口
- ApplicationContext是后期发展出的接口.
- ApplicationContext的功能要更加强大.
- ApplicationContext是启动时默认立刻创建容器中所有对象,获得时直接返回
AOP思想
- 纵向重复,横向抽取.
- spring封装了代理技术,通过代理技术来体现aop思想.我们使用代理体现aop时,不需要我们自己书写代理代码.spring帮我们完成.
spring框架搭建
导包
- 4个核心包,core、bean、context、exception
- 2个日志包,apache.commons.loggin、apache.log4j
准备对象
创建一个类
创建spring配置文件
在src目录下创建applicationContext.xml
导入4个约束(schema)beans、context、tx、aop
配置spring容器随项目启动
原则:一个web项目启动只创建一个spring容器.
操作:
方案一:将spring容器的创建放入静态代码块中.该访问属于自己手动创建容器,容器与web项目没有关联,不推荐.
方案二:spring利用监听器(ServletContext对象创建与销毁监听器)来创建容器.
原理:ContextLoaderListener继承了ServletContextListener,ServletContextListener监听ServletContext的创建与销毁。
代码测试
SE环境测试
//1.创建spring容器
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.获取User对象
User user = ac.getBean("user");
获得spring容器及容器中对象
Web环境下
//1.获得Application域对象
ServletContext sc = ServletActionContext.getServletContext();
//2.调用工具方法从域中取出对象
ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(sc);
//3.获得CustomerService
us = (UserService) ac.getBean("userService");
spring配置详解(xml)
基础配置
bean元素:将对象交给spring容器管理
- name属性:对象的名字,spring根据该名字获得。
- id属性:对象的名字,spring根据该名字获得。
- name属性与id属性区别:
- 1.id出现时间较早.
- 2.id属性必须符合id规范:唯一不能使用特殊字符.
- 3.name属性:可以重复(不推荐重复),也可以使用特殊字符.
- class属性:对象的完整类名。
- scope属性:决定对象的作用域,生命周期。
- singleton(默认值):单例,容器启动时创建单例对象,容器销毁时才销毁单例对象.
- prototype:原型多例,启动时不会创建,每次获得时都会创建新的对象,对象不会放入容器的管理.
- request:web环境下的属性,对象的生命周期为一次请求.
- session:web环境下的属性,对象的生命周期为一次会话.
- init-method|desotory-method属性:指定对象的生命周期。
- init-method:指定对象的初始化方法,会在构造方法调用之后调用.
- destory-method:指定对象的销毁方法,会在容器销毁对象之前调用.
- xml配置
-
sping创建对象方法
静态工厂
//静态工厂
public class UserFactory{
public static User getUser(){
return new User();
}
}
xml配置文件
动态工厂
//动态工厂
public class UserFactory{
public User getUser2(){
return new User();
}
}
xml配置文件
构造方法(推荐)
spring中的DI(依赖注入)
构造方法注入
constructor-arg:指定构造参数
- 定位属性:
- name属性:参数名
- index属性:指定参数在参数列表中的索引
- type属性:指定参数类型
- 注入属性:
- value属性:参数值
- ref属性:注入引用类型
-
-
-
set方法注入
- property标签
-
-
-
- p名称空间
导入p名称空间
xmlns:p="http://www.springframework.org/schema/p"
p:属性名= | p:属性名-ref=
SPEL表达式
SPEL:spring expression language spring 表达式语言,只能引用属性,不能引用对象.
在配置文件中使用#{spel}来引用其他Bean的属性值.
复杂类型注入
Array
1.只有一个值可以直接使用value|ref
2.如果多个值,元素
List
1.只有一个值可以直接使用value|ref
2.如果多个值,元素
|-
|-
Map
|-填写键值对
Properties
|-填写键值对
spring配置详解(注解)
准备工作
导包
|4+2
|spring-aop
导入约束
spring-context-4.2.xsd
开启注解配置
注解
注册对象
@component(“user”)
@controller(“user”)
@service(“user”)
@Repository(“user”)
指定对象域作用域
@Scope(“singleton”)
指定对象生命周期
@PostConstruct 初始化
@PreDestory 销毁
值注入
@value
1.成员变量,直接为成员变量赋值
2.set方法,调用set方法赋值
注入引用类型
1.@AutoWired根据类型自动装配
2.@AutoWired和@Qulifier配合,@Qualifier(“car”)
3.@Resource直接指定注入的对象名,@Resource(name=”car”)
spring整合JDBC(JDBCTemplate)
spring框架提供一个可以完成jdbc操作的对象,该对象可以放置到spring容器中.
spring准备的操作数据库的类,与QueryRunner类的设计与使用几乎完全相同.
导包
- 4+2
- spring-jdbc、spring-tx
- 数据库驱动、c3p0连接池
JDBCTemplate工具类
- jt.update(String sql,Object…params)增删改
- public void save(User u){
- String sql ="insert into t_user value(null,?) ";
- getJdbcTemplate().update(sql,user.getName);
- }
- jt.queryForObject(sql,class,params),查询单个值,并指定返回值类型
- //查询总数
- public Integer getTotalCount(){
- String sql = "select Count(*) from t_user ";
- getJdbcTemplate().queryForObject(sql,Integer.class);
- }
- jt.queryForObject(sql,rowMapper,params),执行查询,并手动封装结果到对象中.返回单个对象
- //根据id查对象
- public User getById(Integer id){
- String sql = "select * from t_user where id=?";
- return getJdbcTemplate().QueryForObject(sql,new RowMapper
(){ - public User mapRow(ResultSet rs,int index ) throws SQLException{
- User user = new User();
- user.setId(rs.getInt("id"));
- user.setName(rs.getString("name"));
- return user;
- }
- },id);
- }
- jt.query(sql,rowMapper,params),执行查询,手动封装结果,返回List
- //查询所有的User
- public List
getAll(){ - String sql = "select * from t_user";
- return getJdbcTemplate().QueryForObject(sql,new RowMapper
(){ - public User mapRow(ResultSet rs,int index) throws SQLException{
- User user = new User();
- user.setId(rs.getInt("id"));
- user.setName(rs.getString("name"));
- return user;
- }
- });
- }
JdBCDaoSupport
继承JdbcDaoSupport,减少一层依赖关系.源码中已经帮我们接收JdbcTemplate
好处:可以减少一级依赖关系.直接将连接池对象注入给Dao即可。
使用DB.properties管理连接信息
- 在src下创建properties文件,文件配置数据库信息
- spring配置文件中读取:
- 在配置中引用,${key}
spring中aop开发
aop&代理
spring中封装的代理技术
- 动态代理
- 局限性:生成代理类时必须基于接口.生成的代理对象实际上就是接口的实现类.
- spring中的aop是希望能够对所有对象生成代理的.基于该动态代理原则会导致
- 项目中很多类无法生成代理.
- CGLib代理
- spring为了能够对项目中所有类生成代理.所以引入了cglib这个第三方代理技术.该代理技术的特点是.对目标对象生成代理时,代理对象是被代理对象的子类.
- hibernate中应用了CGLib代理,懒加载技术中返回的就是cglib代理对象.
aop中的名称解释
aop联盟制定规范
- 连接点 join point:目标对象中所有可以增强的方法.
- 切点 point cut:已经或即将增加的方法.
- 通知 advice:我们需要对目标方法增强的代码.
- 目标对象 target:我们需要增强的对象
- 代理对象 proxy:将通知应用到目标对象生成的对象
- 织入 weaving:将通知织入到目标对象的过程.
- 切面 aspect|advistor:切点+通知
springAOP开发步骤(注解)
- 导包
- 目标对象
- 通知对象
- 配置注解
注解详解
xml中配置
- 注册目标对象
- 注册通知对象
-
- 开启使用注解配置aop
代码中配置注解
- @Aspect 表示该类是通知类
- @Aspect
- pbublic class MyAdvice{}
- @Before(“execution(表达式)”) 前置通知
- @Around(“execution(表达式)”) 环绕通知
- @AfterRunner(“execution(表达式)”) 后置通知
- @After(“execution(表达式)”) 后置通知,不管是否抛异常,都执行
- @AfterThrowing(“execution(表达式)”) 异常拦截通知
- //注册切点
- @Pointcut(execution(* cn.it.service.impl.*ServiceImpl.*(..)))
- public void myPc(){}
- //前置通知
- @Before("MyAdvice.myPc()")
- public void before(){}
springAOP开发步骤(xml)
- 导包
- 目标对象
- 通知对象
- 配置xml
xml配置详解
Spring中的aop事务管理
事务属性
- 传播行为(PROPAGATION)默认选择REQUIRED
- 是否只读(only-read)true|false
- 隔离级别
springAOP事务管理(XML) ###
- 导包
- 创建Dao层对象
- 创建Service层对象
- 创建Spring配置文件
spring文件配置详解
- 配置事务
引入tx约束
springAOP事务管理(注解) ###
- 导包
- 创建Dao层对象
- 创建Service层对象
- 创建Spring配置文件
spring文件配置详解
- 配置注解
- //使用注解管理事务
- @Transactional(paragation=Paragation.REQUIRED,readOnly=false,isolaction=Isolaction.REPEATABLE_READ)
- public class UserServiceImpl implements UserService{
- @Transactional(paragation=Paragation.REQUIRED,readOnly=true,isolaction=Isolaction.REPEATABLE_READ)
- public void transaction()
- }
spring整合hibernate、struts2
导包
- hibernate lib下required
- struts2 apps下struts2-blank(删除与hibernate相同的包)
- spring
- core、context、bean、exception、log4j、logging
- spring-jdbc、spring-tx、spring-orm
- 数据库驱动、c3p0连接池
- spring-aop、spring-aspect
- aspectj织入、aop联盟
- spring-web
- spring-test、junit4
- web jstl
整合spring到web项目
配置监听器,让spring随项目的启动而创建容器
准备spring配置文件
在src目录下创建applicationContext.xml,导入4个约束,bean、context、tx、aop
整合struts2到web项目
创建Action
- 创建Action的三种方式
- pojo(普通java对象,不需要实现任何接口|任何类)
- 实现Action
- 继承ActionSupport
- 获取表单数据的三种方式
- 属性驱动
- 对象驱动
- 模型驱动
创建配置文件
配置入口过滤器
spring整合struts2
配置整合spring常量
方案1:Action对象仍然由struts2创建,spring负责组装依赖.
在action中准备依赖属性
方案2:Action对象创建与依赖注入全都由spring完成
将Action配置到spring容器中
在Action配置中的class属性,填写对象的BeanName
搭建Hibernate框架
准备实体与映射文件
准备实体
映射文件 User.hbm.xml
准备主配置文件
在src目录下创建hibernate.cfg.xml
整合spring与hibernate
整合方式1:使用原生Hibernate配置文件
整合方式2:将hibernate中的配置转移到spring中
将c3p0连接池配置到spring
1.准备DB.properties
2.读取db.properties
3.配置连接池对象,并注入连接配置
4.将连接池对象注入到sessionFactory中
将Dao&Hibernate模板配置到spring
书写Dao类
配置hibernate模板到spring
配置dao到spring
整合AOP事务
1.完成Service
2.配置核心事务管理器
XML|注解事务配置
xml配置
注解
service中使用注解
@Transaction(progation=Progation.REQUIRED,readOnly=true,isolaction=Isolaction.REPEATABLE_READ)
publlic class UserServiceImpl implments UserService{
}
解决no-session问题
配置扩大session作用范围的过滤器
閱讀更多 Java架構解析 的文章