📄 15. spring note.txt
字号:
实施:
1) 创建拦截器类,封装代理行为
implements MethodInterceptor
2) 使用 ProxyFactoryBean 产生代理
属性:
target 目标对象e
proxyInterfaces 代理的接口
interceptorNames 代理要干什么
补充:Advice / Interceptor
除了 MethodInterceptor,还有多种接口可供选择
决定拦截方法的时机
方法前拦截 MethodBeforeAdvice
方法后拦截 AfterReturningAdvice
方法抛出异常后拦截 ThrowsAdvice
围绕方法拦截 MethodInterceptor
MethodInterceptor 通用
Pointcut
切点,相当于过滤器,缩小拦截的方法的范围
概要:
缩小接口或类的范围
缩小方法的范围
实施
1) implements Pointcut
定制过滤规则
ClassFilter
站在接口或类的级别上缩小范围
MethodMatcher
站在方法的级别上所有范围
isRuntime()
return true ,意味着要对参数的值做判断,会调用有三个参数的matchs方法
2) 把 pointcut 和 advice 组合成一个 advisor 对象
advisor = pointcut + advice
使用 DefaultPointcutAdvisor(org.springframework.aop.support.DefaultPointcutAdvisor) 构造 advisor 对象
3) 然后把 advisor 添加到 interceptorNames 中
使用 Spring 提供的Advisor实现
1)NameMetchMethodPointcutAdvisor()
1)RegexpMethodPointcutAdvisor()
思考:使用 ProxyFactoryBean 创建代理的缺点??
1)每个target都要声明ProxyFactoryBean真麻烦!!!
2)能不能以自动匹配的形式创建代理
可以!!!使用自动代理创建器
BeanNameAutoProxyCreator(org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator)
为指定的 bean 自动创建代理
属性:
beanNames
interceptorNames
DefaultAdvisorAutoProxyCreator(org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator)
根据 Advisor 创建代理
day4
四、使用AOP管理事务
帐户管理
Account
IAccountDao
long open(String name,double init);
withdraw(long id,double amount);
deposit(long id,double amount);
List<Account> findByName(String name)
JdbcAccountDao
applicationContex.xml
提供数据源,注入给DAO
实践经验:
Dao 中定义的方法是持久化单元操作,
一个事务可能有若干个单元操作构成,
所以事务逻辑不应该出现在Dao中。
通常事务逻辑应用在业务层(service层)
采用 AOP 管理事务
JdbcTransactionManager implements MethodInterceptor
问题:
1)事务管理器与Dao 都操作同一个连接对象
2)同时,要保证在每个线程都操作不同的连接对象
解决方法:采用ThreadLocal 管理连接对象
创建模板类
管理资源(连接对象)的获取释放
执行SQL
JDBCTemplate
update(String sql,Object[] args);
List<Map> query(String sql);
结论:事务管理棘手
资源的管理棘手
五、对Jdbc的支持
1.提供了JdbcTemplate 简化编程
2.提供了声明的事务管理(与编程的事务管理)
不再把事务逻辑硬编码在程序中,而是在配置文件中定义事务边界
3.把所有checkedException ---> uncheckedException
SQLException--->DataAccessException
应用步骤:
Account
IAccountDao
long open(String name,double amount);
void deposit(long id,double amount);
void withdraw(long id,double amount);
List<Account> findByName(String name);
JdbcAccountDao extends JdbcDaoSupport
继承了两个方法:
setDataSource(DataSource ds)
getJdbcTemplate()
Test
applicationContext.xml
datasource(org.springframework.jdbc.datasource.DriverManagerDataSource)
driverClassName
url
username
password
dao
transactionManager(org.springframework.jdbc.datasource.DataSourceTransactionManager)
dataSource
transactionProxy(org.springframework.transaction.interceptor.TransactionProxyFactoryBean)
target
transactionManager
transactionAttributes
事务的传播属性,七种
调用者:调用当前方法的方法
当前方法:声明事务属性的方法
PROPAGATION_REQUIRED:如果存在一个事务,则支持当前事务。
如果没有事务则开启一个新的事务。
PROPAGATION_SUPPORTS: 如果存在一个事务,支持当前事务。
如果没有事务,则非事务的执行。
PROPAGATION_MANDATORY: 如果已经存在一个事务,支持当前事务。
如果没有一个活动的事务,则抛出异常。
PROPAGATION_REQUIRES_NEW: 总是开启一个新的事务。
如果一个事务已经存在,则将这个存在的事务挂起。
PROPAGATION_NOT_SUPPORTED: 总是非事务地执行,并挂起任何存在的事务。
PROPAGATION_NEVER: 总是非事务地执行,如果存在一个活动事务,则抛出异常
PROPAGATION_NESTED: 如果一个活动的事务存在,则运行在一个嵌套的事务中.
如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行
JdbcTemplate
JdbcTemplate 的API
更新
查询
如果使用Spring 提供的事务管理器 , 你必须使用 Template
六、Spring对 Hibernate 的支持
1) HibernateTemplate
2) 提供声明的事务管理
3) LocalSessionFactoryBean(org.springframework.orm.hibernate3.LocalSessionFactoryBean)
dataSource
应用的步骤(与JDBC有三点不同)
1)HibernateAccountDao extends HibernateDaoSupport
setSessionFactory()
getHibernateTemplate()
2)事务管理器使用 HibernateTransactionManager(org.springframework.orm.hibernate3.HibernateTransactionManager)
3)使用 LocalSessionFactoryBean 获得SessionFactory
1.SpringDAO,SpringORM给持久层带来的好处: 省去try catch代码,事务、异常自动处理
2.访问数据源的两种方法(b/s,c/s): dataSource: JDBC Driver JNDI
7.事务的五个属性: 传播性、只读、
day5Struts1.x流程: B(浏览器)---->ActionServlet-->RequestProcessor-->Action-->JavaBean-->DB request ↓ <-- <-- <-- struts-config.xml
七、在web 应用中使用Spring
概述:
Spring 提供监听器,在应用部署时构造ApplicationContext
ApplicationContext 对象会被绑定在 servlet context 中
Spring 提供了API获得servlet context 中的ApplicationContext
实施步骤:
实现一个web应用,区分 mvc 。
然后,使用spring 管理model :
1) 配置监听器加载上下文
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
2) 在Servlet中获得上下文
WebApplicationContext context=
WebApplicationContextUtils
.getWebApplicationContext(this.getServletContext());
-------------------------
八、对Struts 的支持
辅助 Action 获得 model 对象
两种选择:
Action 不受Spring 管理
Spring为Action 获得 applicationContext 提供支持
Action 受 Spring 管理,
容器为Action注入依赖的 model 对象
使用Spring 的RequestProcessor 或 Action 代理实现
与Struts 集成的两种选择:
1 spring 不管理Action
那只需要关注 Action 怎样获得上下文,两种方式可选择
1) 仍然通过 WebApplicationContextUtils 获得
WebApplicationContextUtils.getWebApplicationContext(
this.getServlet().getServletContext());
2)XxAction extends ActionSupport
继承了一个方法 :getWebApplicationContext
令外可选择 :
DispatchActionSuport
LookupDispatchActionSupport
MappingDispatchActionSupport
优点:结构清楚简单,容易理解
2 让 Spring 管理 Action
把 Action 做为 bean 配置
这样就可以注入Action 依赖的 model 对象了
实现机制,有两种:
改变 RequestProcessor 创建 Action的行为
改由上下文中获得 action
原理:覆盖 processActionCreate
所有请求都给一个特殊的Action,
此 Action execute 方法由上下文中获得 action
然后把处理行为委托给action
return action.execute()
Spring 给我们提供了这两种机制的实现
实施:
1) 把 Action 作为bean 配置,注入其依赖的model组件
applicationContext.xml :
<bean name="/actionpath" class="action class">
<property name="foo">
<ref bean="foo"/>
</property>
</bean>
struts-config.xml :
<action name="/actionpath" type="action class"/>
type 无效
即,等价于:
<action name="/actionpath" />
2) 选择 RequestProcessor 或者 Action ,
使其委托请求给 spring 管理的bean
A)使用DelegatingRequestProcessor
<controller processorClass=
"org.springframework.web.struts.DelegatingRequestProcessor"/>
B)使用 Action 的代理 DelegatingActionProxy
<action path="/actionpath"
type="org.springframework.web.struts.DelegatingActionProxy"/>
Spring Security(安全) 比较JAAS与SpringSecurity JAAS SpringSecurity 与具体的 web容器有关 与具体web容器无关(技术:IOC/AOP)
推荐书籍(学完这课程之后再看):Spring2.x(2.0/2.5)实例指南Spring2企业级开发(图灵出版社)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -