package cd.itcast.spring.day2.event;
public class Customer {
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//=====================================================
package cd.itcast.spring.day2.event;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class CustomerServiceImpl implements ApplicationContextAware {
private ApplicationContext ctx;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.ctx = applicationContext;
}
public void save(Customer c) {
System.out.println("save customer...." + c.getName());
// 向容器发出一个信息:一个customer保存了.
this.ctx.publishEvent(new CustomerEventObject(this, c));
}
}
//=====================================================
package cd.itcast.spring.day2.event;
import org.springframework.context.ApplicationEvent;
public class CustomerEventObject extends ApplicationEvent {
public CustomerEventObject(Object source, Customer c) {
super(source);
this.customer = c;
}
private Customer customer;
public Customer getCustomer() {
return customer;
}
}
//=========================日志事件============================
package cd.itcast.spring.day2.event;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
public class LogServiceImpl implements ApplicationListener<ApplicationEvent> {
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof CustomerEventObject) {
CustomerEventObject eo = (CustomerEventObject) event;
this.log(eo.getCustomer().getName());
}
}
private void log(String msg) {
System.out.println("add log..." + msg);
}
}
//=========================发送邮件事件============================
package cd.itcast.spring.day2.event;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
public class SmsServiceImpl implements ApplicationListener<ApplicationEvent> {
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof CustomerEventObject) {
CustomerEventObject eo = (CustomerEventObject) event;
this.send(eo.getCustomer().getName());
}
}
public void send(String msg) {
System.out.println("send sms..." + msg);
}
}
//========================Spring 配置 注入 bean============================
<bean id="customerService" class="cd.itcast.spring.day2.event.CustomerServiceImpl" />
<bean class="cd.itcast.spring.day2.event.LogServiceImpl" />
<bean class="cd.itcast.spring.day2.event.SmsServiceImpl" />
//=======================TEST ============================
package cd.itcast.spring.day2.event;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringTest {
@Test
public void testService2() {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"application.xml");
CustomerServiceImpl service = ctx.getBean("customerService",
CustomerServiceImpl.class);
Customer c = new Customer();
c.setName("itcast");
service.save(c);
}
}
//=======================TEST ============================
//save customer....itcast
//add log...itcast
//send sms...itcast
|
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- 分散配置 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<context:component-scan base-package="com.atguigu.surveypark.dao.impl,com.atguigu.surveypark.service.impl,com.atguigu.surveypark.listener,com.atguigu.surveypark.struts2.action" />
<!-- 配置(主库)数据源 -->
<bean id="dataSource-main" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverclass}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxPoolSize" value="${c3p0.pool.size.max}" />
<property name="minPoolSize" value="${c3p0.pool.size.min}" />
<property name="initialPoolSize" value="${c3p0.pool.size.ini}" />
<property name="acquireIncrement" value="${c3p0.pool.size.increment}" />
</bean>
<!-- 配置从库数据源 -->
<bean id="dataSource-1" parent="dataSource-main">
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/lsn_surveypark001_1" />
</bean>
<!-- 数据源路由器 -->
<bean id="dataSourceRouter" class="com.atguigu.surveypark.datasource.SurveyparkDataSourceRouter">
<!-- 目标数据源集合 -->
<property name="targetDataSources">
<map>
<entry key="odd" value-ref="dataSource-main" />
<entry key="even" value-ref="dataSource-1" />
</map>
</property>
<!-- 默认数据源集合 -->
<property name="defaultTargetDataSource" ref="dataSource-main" />
</bean>
<!-- 本地回话工厂bean(spring整合hibernate的核心入口) -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSourceRouter" />
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
<property name="mappingDirectoryLocations">
<list>
<value>classpath:com/atguigu/surveypark/model</value>
</list>
</property>
</bean>
<!-- hibnerate事务管理器,用来在service层面上实现事务管理,而且达到平台无关性 -->
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 事务通知 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<!-- 写操作 -->
<tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT"/>
<tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT"/>
<tx:method name="delete*" propagation="REQUIRED" isolation="DEFAULT"/>
<tx:method name="batch*" propagation="REQUIRED" isolation="DEFAULT"/>
<tx:method name="new*" propagation="REQUIRED" isolation="DEFAULT"/>
<tx:method name="clear*" propagation="REQUIRED" isolation="DEFAULT"/>
<tx:method name="toggle*" propagation="REQUIRED" isolation="DEFAULT"/>
<tx:method name="execute*" propagation="REQUIRED" isolation="DEFAULT"/>
<tx:method name="move*" propagation="REQUIRED" isolation="DEFAULT"/>
<!-- 读操作 -->
<tx:method name="load*" propagation="REQUIRED" isolation="DEFAULT" read-only="true"/>
<tx:method name="get*" propagation="REQUIRED" isolation="DEFAULT" read-only="true"/>
<tx:method name="find*" propagation="REQUIRED" isolation="DEFAULT" read-only="true"/>
<tx:method name="*" propagation="REQUIRED" isolation="DEFAULT"/>
</tx:attributes>
</tx:advice>
<!-- 缓存管理器 -->
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="cacheManagerFactoryBean" />
</bean>
<!-- 缓存管理器工厂bean -->
<bean id="cacheManagerFactoryBean" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml" />
</bean>
<!-- 自定义缓存key生成器 -->
<bean id="surveyparkKeyGenerator" class="com.atguigu.surveypark.cache.SurveyparkKeyGenerator" />
<!-- 缓存通知 -->
<cache:advice id="cacheAdvice" cache-manager="cacheManager" key-generator="surveyparkKeyGenerator">
<cache:caching cache="surveyparkCache">
<cache:cacheable method="get*" />
<cache:cacheable method="load*" />
<cache:cacheable method="find*" />
<cache:cache-evict method="save*" all-entries="true" />
<cache:cache-evict method="update*" all-entries="true"/>
<cache:cache-evict method="delete*" all-entries="true"/>
<cache:cache-evict method="clear*" all-entries="true"/>
<cache:cache-evict method="toggle*" all-entries="true"/>
<cache:cache-evict method="move*" all-entries="true"/>
<cache:cache-evict method="batch*" all-entries="true"/>
<cache:cache-evict method="execute*" all-entries="true"/>
</cache:caching>
</cache:advice>
<!-- 日志记录仪 -->
<bean id="logger" class="com.atguigu.surveypark.advice.Logger" />
<!-- aop配置 -->
<aop:config>
<!-- 事务切入点通知 -->
<aop:advisor advice-ref="txAdvice" pointcut="execution(* *..*Service.*(..))" order="2"/>
<!-- 缓存切入点通知 -->
<aop:advisor advice-ref="cacheAdvice" pointcut="execution(* *..*Service.*(..))" order="0"/>
<!-- Logger切面 -->
<aop:aspect id="loggerAspect" ref="logger" order="1">
<aop:around method="record" pointcut="(execution(* *..*Service.save*(..))
or execution(* *..*Service.update*(..))
or execution(* *..*Service.delete*(..))
or execution(* *..*Service.batch*(..))
or execution(* *..*Service.new*(..))
or execution(* *..*Service.move*(..))
or execution(* *..*Service.clear*(..))
or execution(* *..*Service.toggle*(..)))
and !bean(logService)
"/>
</aop:aspect>
</aop:config>
</beans>
hibernate.cfg.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.show_sql">true</property>
</session-factory>
</hibernate-configuration>
jdbc.properties
jdbc.driverclass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/survey?useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=root
c3p0.pool.size.max=10
c3p0.pool.size.min=2
c3p0.pool.size.ini=3
c3p0.pool.size.increment=2
ehcache.xml:
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
<cache name="surveyparkCache"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
</ehcache>
<!-- 自定义缓存key生成器 -->
com.atguigu.surveypark.cache.SurveyparkKeyGenerator
package com.atguigu.surveypark.cache;
import java.lang.reflect.Method;
import org.springframework.cache.interceptor.KeyGenerator;
import com.atguigu.surveypark.util.StringUtil;
/**
* 自定义缓存key生成器
*/
public class SurveyparkKeyGenerator implements KeyGenerator{
public Object generate(Object arg0, Method arg1, Object... arg2) {
String className = arg0.getClass().getSimpleName();
String mname = arg1.getName();
String params = StringUtil.arr2Str(arg2);
String key = className + "@" + arg0.hashCode() + "." + mname + "("+params+")" ;
System.out.println(key);
return key;
}
}
Logger.java
package com.atguigu.surveypark.advice;
import java.util.Map;
import javax.annotation.Resource;
import org.aspectj.lang.ProceedingJoinPoint;
import com.atguigu.surveypark.model.Log;
import com.atguigu.surveypark.model.User;
import com.atguigu.surveypark.service.LogService;
import com.atguigu.surveypark.util.StringUtil;
import com.opensymphony.xwork2.ActionContext;
/**
* Logger
*/
public class Logger {
@Resource
private LogService logService ;
/**
* 记录
*/
public Object record(ProceedingJoinPoint pjp){
Log log = new Log();
try {
ActionContext ac = ActionContext.getContext();
//设置操作人
if(ac != null){
Map<String, Object> session = ac.getSession();
if(session != null){
User user = (User) session.get("user");
if(user != null){
log.setOperator("" + user.getId() + ":" + user.getEmail());
}
}
}
//操作名称
String mname = pjp.getSignature().getName();
log.setOperName(mname);
//操作参数
Object[] params = pjp.getArgs();
log.setOperParams(StringUtil.arr2Str(params));
//调用目标对象的方法
Object ret = pjp.proceed();
//设置操作结果
log.setOperResult("success");
//设置结果消息
if(ret != null){
log.setResultMsg(ret.toString());
}
return ret ;
} catch (Throwable e) {
log.setOperResult("failure");
log.setResultMsg(e.getMessage());
}
finally{
logService.saveEntity(log);
}
return null ;
}
}
|
package com.supinfo.util;
import org.springframework.context.ApplicationContext;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
public class TransactionTemplateUtils {
//DefaultTransactionDefinition
//用户描述事务的隔离级别、超时时间、是否为只读是事务和事务传播规则等控制事务具体行为属性
private static DefaultTransactionDefinition def = new DefaultTransactionDefinition();
//Struts2Utils.getApplicationContext()此处
/*
* public static final String[] beanPath = new String[] { "applicationContext-*.xml"};
*
* public static ApplicationContext getApplicationContext(){
* return new ClassPathXmlApplicationContext(beanPath);
* }
*/
private static ApplicationContext ctx = Struts2Utils.getApplicationContext();
/**
* @描述: 获取 事务管理器
* @方法名: getPlatformTransactionManager
* @throws
*/
public static PlatformTransactionManager getPlatformTransactionManager(){
//从Spring容器中请求事务管理器,用PlatformTransactionManager
return ctx.getBean("transactionManager", PlatformTransactionManager.class);
}
/**
* @描述: 获取 控制计量设备事务管理器状态,不需要设置隔离级别 和 传播性
* @方法名: getTransactionStatus
* @param txManager
* @return TransactionStatus
* @throws
*/
public static TransactionStatus getTransactionStatus(
PlatformTransactionManager txManager) {
return txManager.getTransaction(def);
}
/**
* @描述: 获取事务管理器状态,需要设置隔离级别 和 传播性 通过名称 通过常量形式
* @方法名: getTransactionStatus
* @param txManager 事务管理器
* @param isolationLevel 事务的隔离级别
* @param propagationBehavior 事务传播性
* @return TransactionStatus
* @throws
*/
public static TransactionStatus getTransactionStatus(
PlatformTransactionManager txManager, int isolationLevel,
int propagationBehavior) {
//设置隔离级别
def.setIsolationLevel(isolationLevel);
//设置传播性
def.setPropagationBehavior(propagationBehavior);
//TransactionStatus对象代表着事务的状态。以下代码根据传入的事务定义
//对象返回事务并启动事务
return txManager.getTransaction(def);
}
/**
* @描述: 获取事务管理器状态,需要设置隔离级别 和 传播性 通过名称
* @方法名: getTransactionStatus
* @param txManager 事务管理器
* @param isolationLevelName 隔离级别名称
* @param propagationBehaviorName 隔离级别名称
* @return TransactionStatus
* @throws
*/
public static TransactionStatus getTransactionStatus(
PlatformTransactionManager txManager, String isolationLevelName,
String propagationBehaviorName) {
//设置隔离级别名称
def.setIsolationLevelName(isolationLevelName);
//设置传播性名称
def.setPropagationBehaviorName(propagationBehaviorName);
////TransactionStatus对象代表着事务的状态。以下代码根据传入的事务定义
//对象返回事务并启动事务
return txManager.getTransaction(def);
}
public static void main(String[] args) {
PlatformTransactionManager txManager = TransactionTemplateUtils.getPlatformTransactionManager();
TransactionStatus status = TransactionTemplateUtils.getTransactionStatus(txManager, TransactionDefinition.ISOLATION_DEFAULT, TransactionDefinition.PROPAGATION_MANDATORY);
try {
} catch (Exception e) {
//异常 回滚
txManager.rollback(status);
}
//提交
txManager.commit(status);
}
}
|