整合ssh——spring容器
来源:互联网 发布:mysql分布式事务 编辑:程序博客网 时间:2024/06/06 23:52
spring
spring概述(重点)
当代的企业级应用绝不可能是一个个的独立系统.一般都是部署在多个进行交互的应用,同时这些应用又都有可能与其他企业的相关应用连接,从而构建一个复杂的,跨越internet的分布式企业应用集群.
企业级应用不但有强大的功能,还要能满足未来业务需求的变化,易于升级和维护.
传统JavaEE 解决企业应用问题时的"重量级"架构体系,使它的开发效率,开发难度和实际的性能都令人失望.正在人们苦苦寻找解决办法时,Spring以一个救世主的形象出现在广大的java程序员面前.
Spring的组成模块和几个重要的概念
Spring Core是框架的最基础部分,提供IOC和依赖注入特性.
Spring DAO 提供了JDBC抽象层,简化JDBC编码,同时代码更健壮.
Spring ORM部分对Hibernate等OR映射框架提供了支持.
Spring AOP是基于Spring Core的符合规范的面向方面编程的实现,其重要组成部分是代理,必须理解它们,否则很难用好Spring AOP.
Spring Web是为Spring在Web应用程序中使用提供的支持
依赖注入(DI): 应用组件不应该负责查找资源或者其他依赖的协作对象。配置对象的工作应该由IoC容器负责
控制反转(IOC):它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。
IOC容器:IOC容器就是具有依赖注入功能的容器,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
总结:依赖注入和控制反转可以理解为实现了同一作用就是,将程序之间的关系和数据转移给ioc容器管理,依赖注入和控制反转是框架的普遍都存在的特性。
Spring Core是spring框架中最低层核心的模块。提供了最基本的Ioc思想框架。Spring采用工厂模式管理beans顶级接口是 BeanFactory。
Spring配置实现(重点)
配置实现原理
在web.xml文件中配置ContextLoaderListener,该类实现了ServletContextListener接口,配置此类后当web容器启动时收到事件回调,ContextLoaderListener的监听器方法,加载spring的配置文件,同时创建了WebApplicationContext 对象。(此类为web的上下文对象服务)。
ApplicationContext接口
接口实现类:ClassPathXmlApplicationContext
通过以下方法可以读取配置信息。
ApplicationContextcontext = new ClassPathXmlApplicationContext("bean.xml");
接口实现类:WebApplicationContext
xml基本约束
导入spring的jar包目录下的schema\beans\最新版本
注解约束:导入schema\context 下的最新包
导入包(新版本) : spring-aop-xxxx
基本配置信息
默认放在src下:ApplicationContext.xml的配置
1、开启指定包下及其子包的注解: <context:component-scanbase-package=""></context:component-scan>
2、 Bean元素:
id属性:给被管理的对象起个名字
name属性:是id属性的别名(可省略)
class属性:对象的完整类名
scope属性:处理对象创建方法(处理并发请求)
singleton(默认):单例对象,获取的对象为单例对象,构造方法只执行一次,( action对象建议不要配置为单例的,其它对象层可以采用默认的)。
prototype:标识后,每次获得后才创建,每次创建都是新的
request(了解):web环境下,对象与request生命周期一样
session(了解):与session生命周期一致
init-mathod 属性:(init-mathod ="方法名")配置一个方法(bean中的方法),作为生命周期初始化方法,创建时立即调用。
destory-mathod 属性:(destory-mathod="方法名")配置一个生命销毁方法
import元素:导入其它配置文件:
<importresource="classpath:lm.practice.spring.IHello"/>
注入方式(重点)
使用属性的setter方法注入
Setter方法注入,bean中要有依赖对象的set方法
<beanname="user" cass="" ></bean>
<!--value属性注入:为user对象中名为name的属性注入tom值
ref对象引用注入: user类含有car对象属性,将设置好的car的给到user-->
<prppertyname="name" value="tom"></prpperty>
<prppertyname="car" ref="car"></prpperty>
</bean>
<beanname="car" class="car">
<prppertyname="color" value="red"></prpperty>
<prppertyname="name" value="宾利"></prpperty>
</bean>
使用构造器注入
构造方法注入:bean中构造方法一个是无参的,一个是实例了依赖对象的构造方法
将上面的car对象注入到下面user对象,
使用<constructor-arg>标签:
Name 属性:依赖属性名
Index:构造方法的参数顺序,
type:依赖对象类名
<beanname="user" class="">
<constructor-argname="name" value="tom" index="0" type="java.lang.String"/> <constructor-arg name="car" value="car" />
</bean>
p名称注入(了解)
导入p名称空间
<bean name="user"class="" p:name="tom"p:age="18"></bean> //值注入
<bean name="user"class="" p:name="tom" p:age="18" p:属性名-ref="bean对象" />
spel注入:(了解)
取其它bean的值为自己的值
<beanname="user1" class="">
<prppertyname="name" value="#{user.name}"></prpperty>
<prppertyname="car" ref="car"></prpperty>
</bean>
复杂类型注入(list、map)
<beanname="test" class="">
<property name="list"value="tom"></property> //只有一个值可以按之前的注入
<property name="list">
<list> //向集合中注入多个值(数组,将list换成array)
<value>list1</value>
<value>list2</value>
</list>
</property>
<property name="map">
<map> //向集合中注入多个值(数组,将list换成array)
<entrykey="" value=""></entry>
<entrykey="car" value-ref="car对象"></entry> //map中注入对象
</map>
</property>
</bean>
Spring的日志
为方便bean的实例化过程,spring采用log4j做日志输出,将log4j-1.2.15.jar添加到项目
控制日志输出log4j.properties文件内容如下:
#所有日志的根日志,修改该日志属性对所有日志起作用
log4j.rootLogger=info,console
#输出级别debug
log4j.logger.cn.jbit.facelook=DEBUG
#输出级别info
log4j.logger.com.opensymphony.xwork2=info
#输出源的输入位置是控制台
log4j.appender.console=org.apache.log4j.ConsoleAppender
#采用的布局类
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d%p [%c] - %m%n
Spring对象
1、空参创建
ApplicationContextac = new
2、 静态工厂
创建一个类,构造方法中创建对象
3、实例工厂
使用注解实例:在javabean中:
@Component("类名");
相等于: <bean name="user" class="com.test" />
@Service //servic层
@Controller //web层
@Repository //dao层
作用范围:
设置作用域:@Scope(scopeName=)
赋值(在属性前或set方法前):@Value("tom") //设置初始值
方法前:类@PreConstruct 初始化后调用
@Pre
STS插件
1、手动安装插件
2、安装好spring插件的eclipse
spring 和junit整合测试
导入libs下的 test包
//会帮我们创建容器使用指定配置的文件
测试方法前加入:@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
@Resource(name="user")
private User u; //上面的注解直接创建对象
spring的aop编程(重点!!)
aop使用代理技术的原理
使用代理技术对类的功能进行加强(使用aop思想,在方法执行前后加入增强的方法/加入配置信息,
动态代理(优先):被代理对象要实现接口才能产生代理对象代理方法Proxy.newProxyInstance();
cglib代理:可以对任何类生成代理,原理是对目标对象进行继承代理
如果目标对象被final修饰,则该类无法被cglib代理
名称解释
Joinpoint (连接点):目标对象中可以增强的方法,
Pointcut (切入点):目标对象连接点的集合(可以筛选要增强的方法)
Advice (通知、增强):要增强的代码(代理的代码)
Target(目标对象):被代理的对象
Weaving (织入): 将通知应用到切入点的过程
Proxy (代理) :将通知织入到目标对象后,形成代理对象
aspect(切面):切入点 +通知,两名词相加
spring实现aop的几种方法
准备通知:前置通知--目标方法运行前调用
后置通知--目标方法运行后调用(异常后不调用)
环绕通知 -- 运行前后都调用
异常拦截通知--出现异常调用
后置通知--目标方法运行后调用(异常后也调用)
配置进行织入,织入目标对象:
一:编程式代理对象硬编码
1、针对目标对象写一个实现类(切面),要实现代理接口MethodBeforeAdvice/afterxx,重写接口的方法,实现的接口直接决定了在目标对象前或后增强功能
2、先配置目标对象 bean 和代理 bean
3、配置 代理 bean : class =ProxyFactoryBean
<bean id="helloProxy"class="org.springframework.aop.framework.ProxyFactoryBean">
<!--目标对象实现的接口 -->
<propertyname="proxyInterfaces" value="com.robin.IHello" />
<!-- 目标对象的 bean -->
<propertyname="target" ref="helloSpeaker" />
<!-- 配置通知的 bean -->
<property name="interceptorNames">
<list>
<value>logBeforeAdvice</value>
</list>
</property>
</bean>
二.xml配置代理对象配置
1、写通知类实现MethodInterceptor 接口重写invoke()方法(这个接口就诠释了动态代理的底层处理),注意要运用proceed()方法,执行目标对象方法
例如:
public class LogInterceptorimplements MethodInterceptor {
private Loggerlogger = Logger.getLogger(this.getClass().getName());
public Object invoke(MethodInvocation m)throws Throwable {
logger.log(Level.INFO,"method starts..." + m.getMethod());
Objectresult = null;
try {
result = m.proceed(); // 如果有多个interceptor
//转给下一个interceptor来处理 如果没有执行目标对象的方法 再层层返回 interceptor栈
} finally {
logger.log(Level.INFO,"method ends..." + m.getMethod() + "\n");
}
returnresult;
}
}
2、配置通知和目标对象,配置 ProxyFactoryBean(同上)
三.xml配置无代理对象使用<aop>标签配置
1、写通知类 不需要实现接口,直接创建通知方法
void xbefore(JoinPointjointPoint) //JoinPoint包含切面对象信息可以省略
2、配置实现目标bean 通知bean(需要插入的方法类)
3、只用<aop>标签配置xml
<aop:config>
<!--引用advice通知 -->
<aop:aspectid="logging" ref="logBeforeAdvice">
<!--advice类型时机 -->
<!--pointcut切面属性设置 表达式匹配 *任何返回值类型符合
com.robin.IHello.*接口任意方法符合 (..)任何参数 -->
<!-- 例如:在目标对象前,任意返回值的IHello接口下的所有方法前插入,参数不限,插入的增强方法为xbefore-->
<aop:beforepointcut="execution(* com.robin.IHello.*(..))"method="xbefore"/>
</aop:aspect>
</aop:config>
将上面的aop配置换一种写法:
<aop:config>
<aop:pointcutexpression="execution(* com.robin.IHello.*(..))"id="pc"/>
<aop:aspectref="logBeforeAdvice" >
<!--指定通知类中的方法如何代理:指定名为before方法作为前置通知 -->
<aop:beforemethod="xbefore" pointcut-ref="pc" />
</aop:aspect>
</aop:config>
四、使用注解配置 aop
1、 配置目标bean 以及 通知bean
2、开启注解配置aop <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
@Aspect //@Aspect说明该类是个切面
public class TestAspect {
//@Pointcut 定义一个切入点,对com.yyj.service包及子包下的所有方法
//方法无方法体,为方便同类中其他方法使用此处配置的切入点
@Pointcut("execution(*com.yyj.service.*.*(..))")
public void testPointCut(){
}
@Before("aspect()") //使用上面的切入点
public voidbefore(JoinPoint joinPoint){
if(log.isInfoEnabled()){
log.info("before" + joinPoint);
}
}
Spring配置aop的详细步骤:
导包:(目前为止 spring有10个包: 4+2日志)
+ spring的aop包: aop和 aspects
+spring需要的第三方aop包: aopalliance aspectj.xx
准备目标对象(需要增强的类如 userServic)
配置xml
配置目标对象:
<beanname="" class=""></>
配置通知对象:
<beanname="" class=""></>
配置将通知织入目标对象:
<!-- 1. 配置目标对象 -->
<bean name="userService"class="cn.itcast.service.UserServiceImpl" />
<!-- 2. 配置通知对象 MyAdvice为通知类! -->
<beanname="myAdvice" class="cn.itcast.d_springaop.MyAdvice"></bean>
<!-- 3. 配置将通知织入目标对象 -->
<aop:pointcutexpression="execution(* cn.itcast.service.*ServiceImpl.*(..))"id="pc"/>
<aop:aspectref="myAdvice" >
<!--指定通知类中的方法如何代理:指定名为before方法作为前置通知 -->
<aop:before method="before"pointcut-ref="pc" />
<!-- 后置 -->
<aop:after-returningmethod="afterReturning" pointcut-ref="pc" />
<!-- 环绕通知 -->
<aop:aroundmethod="around" pointcut-ref="pc" />
<!-- 异常拦截通知 -->
<aop:after-throwingmethod="afterException" pointcut-ref="pc"/>
<!-- 后置 -->
<aop:aftermethod="after" pointcut-ref="pc"/>
</aop:aspect>
</aop:config>
spring整合hibernate
配置获取SessionFactory
1、在applicationContext.xml中导入hibernate.cfg.xml文件,获得sessionFactory
2、使用SessionFactory 配置Dao层对象,
<!-- 使用LocalSessionFactoryBean 可以导入很多形式的 hibernatede1配置信息-->
<beanid="sessionFactory"class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<propertyname="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>
<!-- 2、配置DAO层,各种方法都需要使用sessionFactory完成curd操作,只有class不同 -->
<bean id="userDao"class="com.juan.oa.dao.impl.UserDaoHibimpl" >
<propertyname="sessionFactory" ref="sessionFactory" />
</bean>
配置扩展
LocalSessionFactoryBean可以配置多种hibernate信息。例如:
configLocation 属性加载hibernate配置文件创建sessionFactory 连接数据库
mappingResources属性导入映射文件
hibernateProperties属性设置hibernate属性
dataSource属性注入数据源实现不同数据库切换
整合后Dao层的写法
方法一:直接配置使用hibernate的操作:
1、在Dao中定义sessionFactory对象属性,然后获得session完成cord操作
方法二:使用spring简化增删改操作:实现 HibernateDaoSupport接口
2、通过getHibernateTemplate()方法获得 HibernateTemplate,在通过此类的方法进行简单的增删改查
类似:JdbcTemplate /JpaJdbcTemplate /ConnectionCallback<T>/JpaDaoSupport /JdbcDaoSupport
例如:List list = getHibernateTemplate().findByExample(User);
方法三:使用spring简化查询操作:实现 HibernateDaoSupport接口
List lists =getHibernateTemplate().executeFind(new HibernateCallback() {
public ObjectdoInHibernate(Session session) throws HibernateException, SQLException {
String hql= "from User where name=? and password=?";
Query query= session.createQuery(hql);
query.setParameter(0,user.getName());
query.setParameter(1,user.getPassword());
List list =query.list();
returnlist;
}
});
结论
1、spring提供了很多模板 整合Dao技术: orm持久化技术有 jdbc /shibernate3.0 / ibatis /jpa
2、spring中 可以操作数据库的对象,该对象封装了jdbc的技术:
JDBCTemplate => JDBC模板对象 与 dbutils的 QueryRunner 非常相似
ComboPooledDataSourcedataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql:///hibernate_32");
dataSource.setUser("root");
dataSource.setPassword("1234");
//1 创建JDBC模板对象
JdbcTemplate jt = newJdbcTemplate();
jt.setDataSource(dataSource);
//2 书写sql,并执行
Stringsql = "insert into t_user values(null,'rose') ";
jt.update(sql);
将hibernate的配置转移到spring
1、 导包:4+2、spring-test、spring-aop、junit4类库、c3p0连接池、JDBC驱动、spring-jdbc、spring-tx事务
(配置读取properties文件)
<!-- 指定spring读取db.properties配置数据库 -->
<!-- 1.将连接池放入spring容器,获得数据源 -->
<context:property-placeholderlocation="classpath:db.properties" />
<beanname="dataSource"class="com.mchange.v2.c3p0.ComboPooledDataSource" >
<propertyname="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<propertyname="driverClass" value="${jdbc.driverClass}" ></property>
<propertyname="user" value="${jdbc.user}" ></property>
<propertyname="password" value="${jdbc.password}"></property>
</bean>
<!-- 2.将JDBCTemplate放入spring容器
注意:如果没有配置jdbc模板对象,则不能使用此c3p0提供的模板操作
可以直接使用数据源配置Dao层,Dao层实现 HibernateDaoSupport接口
通过getHibernateTemplate().executeFind()方法,写hql语句,操作数据库
-->
<bean name="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate" >
<propertyname="dataSource" ref="dataSource" ></property>
</bean>
<!-- 3.将UserDao放入spring容器 -->
<bean name="userDao"class="cn.itcast.a_jdbctemplate.UserDaoImpl" >
<!--<property name="jt" ref="jdbcTemplate"></property> -->
<propertyname="dataSource" ref="dataSource" ></property>
</bean>
spring封装的事务操作
DriverManagerDataSource --> DataSourceTransactionManager-->
1、spring封装了一个接口,用来应对不同平台操作事务的不同: PlatformTransactionManager接口,
实现类:DataSourceTransactionManager
HibernateTransitionmanager (结合hibernate,用SessionFactory获取事务管理对象)
注意:在spring中玩事务管理.最为核心的对象就是TransactionManager对象
2、 spring事务的属性:隔离级别:是否只读:事务的传播行为(当多个方法应放在同一事务中时,使用propagation属性,="REQUIRED"时为存在事务则不再创建新事务。)
spring管理事务的三种方式
第一种:编程式
只通过配置获得DataSource,通过数据源获取事务管理
切面程序:
private DataSourceTransactionManagertransactionManager;//事务管理器
private DefaultTransactionDefinitiondef;//用来设置事务特性
private JdbcTemplate jdbcTemplate;
public void setDataSource(DriverManagerDataSourcedataSource) {
transactionManager=newDataSourceTransactionManager(dataSource);
jdbcTemplate=newJdbcTemplate(dataSource);
def=newDefaultTransactionDefinition();
//设置事务的特性
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
//存在事务就使用,不存在创建新事务
}
TransactionStatustransactionStatus= transactionManager.getTransaction(def);
使用传统的jdbcc获取数据源配置:
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"><!-- 这里获得基本jdbc连接 -->
<propertyname="driverClassName" value="com.mysql.jdbc.Driver"/>
<propertyname="url" value="jdbc:mysql://localhost:3306/test" />
<propertyname="username" value="root" />
<propertyname="password" value="123456" />
</bean>
<bean id="userDao"class="com.robin.UserDao">
<propertyname="dataSource" ref="dataSource" />
</bean>
第二种:编程式:有代理对象的配置
1、只需定义jdbcTemplate属性 通过setDataSource方法获取配置的数据源给jdbcTemplate赋值
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
jdbcTemplate = newJdbcTemplate(dataSource);
}
<beanid="transactionManager" //定义事务管理器bean
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<propertyname="dataSource" ref="dataSource"/>
</bean>
<bean id="userDAO" class="com.robin.UserDAO">
<propertyname="dataSource" ref="dataSource"/>
</bean>
<bean id="userDAOProxy" //定义userDao的代理对象
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<propertyname="proxyInterfaces"> //提供接口信息给代理对象
<list>
<value>com.robin.IUserDAO</value> //连接点是接口的方法中
</list>
</property>
<property name="target"ref="userDAO"/> //目标对象 真实对象
<propertyname="transactionManager" ref="transactionManager"/> //引用事务管理器
<propertyname="transactionAttributes"> //事务特性设置
<props>
<propkey="insert*">PROPAGATION_REQUIRED</prop> //传播行为 </props>
</property>
</bean>
第三种:无代理对象的xml配置
先配置一个事务通知,在使用aop织入到目标方法
<!-- isolation:隔离级别
propagation:传播行为
read-only:是否只读-->
<!-- 定义的事务的advice 标签,时机:开始和结束,动作:针对insert* find* -->
<tx:advice id="txAdvice"transaction-manager="transactionManager">
<tx:attributes> <!-- 定义事务属性 -->
<!-- 定义事务的语义 insert*开头的方法-->
<tx:methodname="insert*" propagation="REQUIRED"/>
<!-- 定义事务的语义 find*开头的方法 -->
<tx:methodname="find*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- 织入 -->
<aop:config>
<!-- 切入点 包含连接点com.robin.IUserDAO包下所有方法,用advice增强处理 -->
<aop:pointcutid="userDAOPointcut"
<!--配置切点表达式 -->
expression="execution(*com.juan.ssh.test2.UserDao.*(..))"/>
<!--将连接点和advice关联告诉被通知者advisor -->
<aop:advisoradvice-ref="txAdvice" pointcut-ref="userDAOPointcut"/>
</aop:config>
第四种注解配置事务:(导入tx约束)
1、 开启使用注解管理aop事务 transaction-manager:事务管理器要在之前配置它的bean。注意:proxy-target-class属性为true时,是类的代理,false接口的代理
<tx:annotation-driven/>
<tx:annotation-driventransaction-manager="transactionManager"proxy-target-class="false" />
2、使用·注解 :在类前使用注解 @Transactional (注解的参数查资料),也可以在接口上使用
事物传播行为介绍:
@Transactional(propagation=Propagation.REQUIRED)
如果有事务, 那么加入事务, 没有的话新建一个(默认情况下)
事务隔离级别:
@Transactional(isolation =Isolation.REPEATABLE_READ) 可重复读(会出现幻读)
jdbc结论:
1、通过各种连接池或框架自带连接获取DataSource(数据源)
2、使用DataSource获得sessionFactory(工厂)
3、使用sessionFactory获取事务处理对象TransactionTemplate(事务模板)
例如:
TransactionTemplate transactionTemplate= new TransactionTemplate( new HibernateTransactionManager(getSessionFactory()));
4、如果在Spring的配置文件中引用hibernate.cfg.xml文件,那么要记住,hibernate的事务,默认自动提交是关闭的,
这时在spring中配置事务就可能会失败。正确的做法是将hibernate的配置转移到spring中。
5、注意,使用spring来管理事务要记住,默认只有运行错误才会回滚,而检查错误是不会回滚的。
- 整合ssh——spring容器
- SSH与SSM学习之SSH整合02——单独配置Spring容器
- SSH—Struts2整合Spring
- SSH与SSM学习之SSH整合04——Struts2与Spring整合
- SSH与SSM学习之SSH整合06——Hibernate与Spring整合
- SSH与SSM学习之SSH整合07——Spring整合c3p0连接池
- SSH与SSM学习之SSH整合08——Spring整合Hibernate环境操作数据库
- SSH——浅谈Spring中的IOC容器
- struts+spring+hibernate——ssh整合步骤
- spring学习笔记(6)——ssh框架整合
- SSH整合——spring跟hibernate兼容问题
- SSH框架——整合Demo(Struts、Spring、Hibernate)
- ssh环境搭建——spring与hibernate整合
- SSH(第三步)—— 整合Struts2和Spring
- SSH(第五步)—— 整合Hibernate和Spring
- Spring容器整合WebSocket
- ssh整合 spring getSession()
- ssh 整合struts+spring
- 网页爬虫《二》之动态网页
- Django 快速搭建博客 第四节(hello world视图)
- Linux下编译OpenJDK源码以及在Eclipse中调试Hotspot虚拟机
- 抽象类练习
- 用GDB调试程序(六)
- 整合ssh——spring容器
- 两个数的最大公约数
- 基于文件操作的留言系统
- Python时间获得及格式转换
- 多线程初探之生产者消费者
- Mybatis selectOne方法执行sql有数据返回为null
- 用GDB调试程序(七)
- Cheerleaders(uva 11806)
- 数组中重复的数字