标签:
//现在,把对象的创建交给spring的IOC容器 Resource resource = new ClassPathResource("haust/vk/a_hello/applicationContext.xml"); //创建容器对象(Bean的工厂), IOC容器=工厂类+ applicationContext.xml BeanFactory factory = new XmlBeanFactory(resource); // User user =(User) factory.getBean("user"); //得到IOC容器对象 ApplicationContext ac = new ClassPathXmlApplicationContext("haust/vk/a_hello/applicationContext"); //从容器中获取bean User user =(User) ac.getBean("user"); System.out.println(user);
//得到IOC容器对象【用实现类,因为要调用销毁的方法】 ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("cn/itcast/a_hello/applicationContext.xml"); System.out.println("-----容器创建-----"); //从容器中获取bean User user1 =(User) ac.getBean("user"); User user2 =(User) ac.getBean("user"); System.out.println(user1); System.out.println(user2); //销毁容器对象 ac.destroy();
<!-- spring 配置 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/classes/bean-*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
// 接口
public interface IUserDao {
void save();
} |
/**
* 目标对象
*/
public class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("-----已经保存数据!!!------");
}
|
/**
* 代理对象(静态代理)
* 代理对象,要实现与目标对象一样的接口
*/
public class UserDaoProxy implements IUserDao{
private IUserDao target;
public UserDaoProxy(IUserDao target) {
super();
this.target = target;
}
@Override
public void save() {
System.out.println("开始事务。。。");
target.save();//执行目标对象方法
System.out.println("关闭事务。。。");
}
} |
public class App {
public static void main(String[] args) {
//目标对象
IUserDao target = new UserDao();
//代理
IUserDao proxy1=new UserDaoProxy(target);
proxy1.save();
}
} |
// 接口
public interface IUserDao {
void save();
} |
/**
* 目标对象
*/
public class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("-----已经保存数据!!!------");
}
} |
/**
* 给所有的dao创建代理对象【动态代理】
* 代理对象,不需要实现接口
*/
public class ProxyFactory {
private Object target;
public ProxyFactory(Object target) {
super();
this.target = target;
}
public Object getProxyInstance() {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("开启事务。。。。");
//执行目标程序
Object returnValue = method.invoke(target, args);
System.out.println("提交事务。。。。");
return returnValue;
}
});
}
} |
public class App {
public static void main(String[] args) {
//创建目标对象
IUserDao target = new UserDao();
//输出原始类型 class haust.vk.b_dynamic.UserDao
System.out.println(target.getClass());
//给目标对象创建 代理代理对象
IUserDao proxy=(IUserDao) new ProxyFactory(target).getProxyInstance();
// class $Proxy0 内存中动态生成的代理对象
System.out.println(proxy.getClass());
//执行方法 代理对象
proxy.save();
}
} |
public class UserDao {
public void save() {
System.out.println("--------已经保存数据-------");
}
} |
/**
* Cglib子类代理工厂
* (对UserDao 在内存中动态构建一个子类对象)
*/
public class ProxyFactory implements MethodInterceptor{
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
//给目标对象创建代理对象
public Object getProxyInstance() {
//1.设置工具类
Enhancer enhancer = new Enhancer();
//2.设置父类
enhancer.setSuperclass(target.getClass());
//3.设置回调函数
enhancer.setCallback(this);
//4.创建子类(代理对象)
return enhancer.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("开始事务。。。");
//执行目标对象的方法
Object returnValue = method.invoke(target, args);
System.out.println("提交事务。。。。");
return returnValue;
}
|
public class App {
public static void main(String[] args) {
//目标对象
UserDao target = new UserDao();
//class class haust.vk.c_cglib.UserDao
System.out.println(target.getClass());
//代理对象
UserDao proxy=(UserDao) new ProxyFactory(target).getProxyInstance();
//UserDao 的子类:class haust.vk.c_cglib.UserDao$$EnhancerByCGLIB$$6e26a71
System.out.println(proxy.getClass());
//执行代理对象的方法
proxy.save();
}
|
public interface IUserDao {
void save();
} |
import javax.annotation.Resource;
import org.springframework.stereotype.Component;
@Component
public class UserDao implements IUserDao{
@Resource
private Aop aop;
@Override
public void save() {
aop.begin();
System.out.println("打印核心业务");
aop.commit();
}
} |
import org.springframework.stereotype.Component;
@Component
public class Aop {
//重复执行的代码
public void begin() {
System.out.println("开始事务");
}
public void commit() {
System.out.println("提交事务事务");
}
} |
<!-- 开启注解扫描 -->
<context:component-scan base-package="haust.vk.d_myaop"></context:component-scan> |
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
ApplicationContext ac=new ClassPathXmlApplicationContext("haust/vk/d_myaop/bean.xml");
@Test
public void testMyaop() throws Exception {
IUserDao dao= (IUserDao) ac.getBean("userDao");
dao.save();
}
}
|
public interface IUserDao {
void save();
}
|
import org.springframework.stereotype.Component;
@Component
public class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("打印核心业务");
}
} |
import org.springframework.stereotype.Component;
@Component
public class Aop {
//重复执行的代码
public void begin() {
System.out.println("开始事务");
}
public void commit() {
System.out.println("提交事务事务");
}
} |
|
<!-- 开启注解扫描 -->
<context:component-scan base-package="haust.vk.d_myaop1"></context:component-scan>
<!-- 调用工厂方法 返回UserDao代理的对象 -->
<bean id="userDao_proxy" class="haust.vk.d_myaop1.ProxyFactory" factory-method="getProxyInstance">
<constructor-arg index="0" ref="userDao"></constructor-arg>
<constructor-arg index="1" ref="aop"></constructor-arg>
</bean> |
|
public interface IUserDao {
void save();
} |
/*
* 对象保护
*/
@Component
public class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("=============核心业务:保存=======");
}
} |
@Component
@Scope("prototype")
public class OrderDao {
public void save() {
System.out.println("===========核心业务:保存!!!=============");
}
} |
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 开启注解扫描 -->
<context:component-scan base-package="haust.vk.e_aop_anno"></context:component-scan>
<!-- 开启AOP注解方式 -->
<aop:aspectj-autoproxy ></aop:aspectj-autoproxy>
|
//指定当前类为切面类
@Aspect
@Component
public class Aop {
//指定切入点 表单式:拦截哪些方法;即为那些类生成代理对象
//其上 表示拦截haust.vk.e_aop_anno包下的所有类及其所有public方法
//切入点
@Pointcut("execution(* haust.vk.e_aop_anno.*.*(..))")
public void pointCut_(){
}
//前置通知 : 在执行目标方法之前执行
@Before("pointCut_()")
public void begin(){
System.out.println("开始事务/异常");
}
// 后置/最终通知:在执行目标方法之后执行 【无论是否出现异常最终都会执行】
@After("pointCut_()")
public void after(){
System.out.println("提交事务/关闭");
}
// 返回后通知: 在调用目标方法结束后执行 【出现异常不执行】
@AfterReturning("pointCut_()")
public void afterReturning(){
System.out.println("afterReturning");
}
// 异常通知: 当目标方法执行异常时候执行此关注点代码
@AfterThrowing("pointCut_()")
public void afterThrowing(){
System.out.println("AfterThrowing");
}
// 环绕通知:环绕目标方式执行
@Around("pointCut_()")
public void around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕前");
pjp.proceed();
System.out.println("环绕后");
}
} |
public class App {
ApplicationContext ac = new ClassPathXmlApplicationContext("haust/vk/e_aop_anno/bean.xml");
// 目标对象有实现接口,spring会自动选择“JDK代理”
@Test
public void testApp() throws Exception {
IUserDao userDao = (IUserDao) ac.getBean("userDao");
System.out.println(userDao.getClass());//$Proxy001
userDao.save();
}
// 目标对象没有实现接口, spring会用“cglib代理”
@Test
public void testCglib() throws Exception {
OrderDao orderDao = (OrderDao) ac.getBean("orderDao");
System.out.println(orderDao.getClass());
orderDao.save();
}
@Deprecated
// 共性问题:如果目标对象有实现接口,在从容器中获取目标对象的时候,只能通过接口接收对象。
public void testApp2() {
// 错误代码: 只能用接口接收
UserDao userDao = (UserDao) ac.getBean("userDao");
System.out.println(userDao.getClass());//$Proxy001
userDao.save();
}
@Test
public void testGetObj() throws Exception {
OrderDao orderDao1 = (OrderDao) ac.getBean("orderDao");
OrderDao orderDao2 = (OrderDao) ac.getBean("orderDao");
System.out.println(orderDao1);
System.out.println(orderDao2);
}
} |
public interface IUserDao {
void save();
} |
public class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("=============核心业务:保存=======");
}
} |
public class OrderDao {
public void save() {
System.out.println("===========核心业务:保存!!!=============");
}
}
|
import org.aspectj.lang.ProceedingJoinPoint;
//指定当前类为切面类
public class Aop {
//前置通知 : 在执行目标方法之前执行
public void begin(){
System.out.println("开始事务/异常");
}
// 后置/最终通知:在执行目标方法之后执行 【无论是否出现异常最终都会执行】
public void after(){
System.out.println("提交事务/关闭");
}
// 返回后通知: 在调用目标方法结束后执行 【出现异常不执行】
public void afterReturning(){
System.out.println("afterReturning");
}
// 异常通知: 当目标方法执行异常时候执行此关注点代码
public void afterThrowing(){
System.out.println("AfterThrowing");
}
// 环绕通知:环绕目标方式执行
public void around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕前");
pjp.proceed();
System.out.println("环绕后");
}
} |
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- dao实例 -->
<bean id="userDao" class="haust.vk.f_aop_xml.UserDao"></bean>
<bean id="orderDao" class="haust.vk.f_aop_xml.OrderDao"></bean>
<!-- 切面类 -->
<bean id="aop" class="haust.vk.f_aop_xml.Aop"></bean>
<!-- Aop配置 -->
<aop:config>
<!-- 定义一个切入点表达式: 拦截哪些方法 -->
<aop:pointcut expression="execution(* haust.vk.f_aop_xml.*.*(..))" id="pt"/>
<!-- 切面 -->
<aop:aspect ref="aop">
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="pt"/>
<!-- 前置通知: 在目标方法调用前执行 -->
<aop:before method="begin" pointcut-ref="pt"/>
<!-- 后置通知: -->
<aop:after method="after" pointcut-ref="pt"/>
<!-- 返回后通知 -->
<aop:after-returning method="afterReturning" pointcut-ref="pt"/>
<!-- 异常通知 -->
<aop:after-throwing method="afterThrowing" pointcut-ref="pt"/>
</aop:aspect>
</aop:config>
</beans> |
public class App {
ApplicationContext ac =
new ClassPathXmlApplicationContext("haust/vk/f_aop_xml/bean.xml");
// 目标对象有实现接口,spring会自动选择“JDK代理”
@Test
public void testApp() {
IUserDao userDao = (IUserDao) ac.getBean("userDao");
System.out.println(userDao.getClass());//$Proxy001
userDao.save();
}
// 目标对象没有实现接口, spring会用“cglib代理”
@Test
public void testCglib() {
OrderDao orderDao = (OrderDao) ac.getBean("orderDao");
System.out.println(orderDao.getClass());
orderDao.save();
}
} |
<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- dao 实例--> <bean id="userDao"class="cn.itcast.g_pointcut.UserDao"></bean> <bean id="orderDao"class="cn.itcast.g_pointcut.OrderDao"></bean> <!--切面类--> <bean id="aop"class="cn.itcast.g_pointcut.Aop"></bean> <!--Aop配置--> <aop:config> <!--定义一个切入点表达式:拦截哪些方法--> <!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.*.*(..))" id="pt"/>--> <!--【拦截所有public方法】--> <!--<aop:pointcut expression="execution(public * *(..))" id="pt"/>--> <!--【拦截所有save开头的方法】--> <!--<aop:pointcut expression="execution(* save*(..))" id="pt"/>--> <!--【拦截指定类的指定方法,拦截时候一定要定位到方法】--> <!--<aop:pointcut expression="execution(public * cn.itcast.g_pointcut.OrderDao.save(..))" id="pt"/>--> <!--【拦截指定类的所有方法】--> <!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.*(..))" id="pt"/>--> <!--【拦截指定包,以及其自包下所有类的所有方法】--> <!--<aop:pointcut expression="execution(* cn..*.*(..))" id="pt"/>--> <!--【多个表达式】--> <!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) || execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>--> <!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) or execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>--> <!--下面2个且关系的,没有意义--> <!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) && execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>--> <!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) and execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>--> <!--【取非值】--> <!--<aop:pointcut expression="!execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>--> <aop:pointcut expression=" not execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/> <!--切面--> <aop:aspect ref="aop"> <!--环绕通知--> <aop:around method="around" pointcut-ref="pt"/> </aop:aspect> </aop:config> </beans>
public class Dept {
private int deptId;
private String deptName;
public int getDeptId() {
return deptId;
}
public void setDeptId(int deptId) {
this.deptId = deptId;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
} |
<!-- 1. 数据源对象: C3P0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///hib_demo"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
<property name="initialPoolSize" value="3"></property>
<property name="maxPoolSize" value="10"></property>
<property name="maxStatements" value="100"></property>
<property name="acquireIncrement" value="2"></property>
</bean>
<!-- 2. 创建JdbcTemplate对象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- dao 实例 -->
<bean id="userDao" class="haust.vk.h_jdbc.UserDao1">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
</beans> |
public class UserDao3 {
// IOC容器注入
private DataSource dataSource;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void save() {
try {
String sql = "insert into t_dept(deptName) values(‘test‘);";
Connection con = null;
Statement stmt = null;
// 连接对象
con = dataSource.getConnection();
// 执行命令对象
stmt = con.createStatement();
// 执行
stmt.execute(sql);
// 关闭
stmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
} |
public class UserDao2 {
/*
* 保存方法
* 需求优化的地方:
* 1. 连接管理
* 2. jdbc操作重复代码封装
*/
public void save() {
try {
String sql = "insert into t_dept(deptName) values(‘test‘);";
Connection con = null;
Statement stmt = null;
Class.forName("com.mysql.jdbc.Driver");
// 连接对象
con = DriverManager.getConnection("jdbc:mysql:///hib_demo", "root", "root");
// 执行命令对象
stmt = con.createStatement();
// 执行
stmt.execute(sql);
// 关闭
stmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
} |
public class UserDao1 {
// IOC容器注入
// private DataSource dataSource;
// public void setDataSource(DataSource dataSource) {
// this.dataSource = dataSource;
// }
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<Dept> list = jdbcTemplate.query(sql,new MyResult(), id);
return (list!=null && list.size()>0) ? list.get(0) : null;
}
public List<Dept> getAll() {
String sql = "select * from t_dept";
List<Dept> list = jdbcTemplate.query(sql, new MyResult());
return list;
}
class MyResult implements RowMapper<Dept>{
// 如何封装一行记录
@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;
}
}
} |
public class Dept {
private int deptId;
private String deptName;
public int getDeptId() {
return deptId;
}
public void setDeptId(int deptId) {
this.deptId = deptId;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
}
|
public class DeptDao {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void save(Dept dept){
String sql="insert into t_dept (deptName) values(?) ";
jdbcTemplate.update(sql,dept.getDeptName());
}
}
|
public class DeptService {
private DeptDao deptDao;
public void setDeptDao(DeptDao deptDao) {
this.deptDao = deptDao;
}
/**
* 事务控制
*/
public void save(Dept dept) {
//第一次调用
deptDao.save(dept);
//int i = 1/0;
//第二次调用
deptDao.save(dept);
}
}
|
<!-- 1.数据源对象: c3p0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///hib_demo"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
<property name="initialPoolSize" value="3"></property>
<property name="maxPoolSize" value="10"></property>
<property name="maxStatements" value="100"></property>
<property name="acquireIncrement" value="2"></property>
</bean>
<!-- JdbcTemplate 工具类实例 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- dao实例 -->
<bean id="deptDao" class="haust.vk.a_tx.DeptDao">
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
<!-- service 实例 -->
<bean id="deptService" class="haust.vk.a_tx.DeptService">
<property name="deptDao" ref="deptDao"></property>
</bean>
<!-- #############5. Spring声明式事务管理配置############### -->
<!-- 5.1 配置事务管理器类 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 5.2配置事务增强(如果管理事务) -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="*" read-only="false"/>
</tx:attributes>
</tx:advice>
<!-- 5.3 Aop配置: 拦截哪些方法(切入点表表达式) + 应用上面的事务增强配置 -->
<aop:config>
<aop:pointcut expression="execution(* haust.vk.a_tx.DeptService.save(..))" id="pt"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
</aop:config>
|
public class App {
@Test
public void testApp() throws Exception {
ApplicationContext ac=new ClassPathXmlApplicationContext("haust/vk/a_tx/bean.xml");
//模拟数据
Dept dept= new Dept();
dept.setDeptName("测试 : 开发部");
DeptService deptService = (DeptService) ac.getBean("deptService");
deptService.save(dept);
}
}
|
public class Dept {
private int deptId;
private String deptName;
public int getDeptId() {
return deptId;
}
public void setDeptId(int deptId) {
this.deptId = deptId;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
}
|
@Repository
public class DeptDao {
@Resource
private JdbcTemplate jdbcTemplate;
public void save(Dept dept){
String sql="insert into t_dept (deptName) values(?) ";
jdbcTemplate.update(sql,dept.getDeptName());
}
}
|
@Service
public class DeptService {
//部门dao
@Resource
private DeptDao deptDao;
//日志dao
@Resource
private LogDao logDao;
/**
* 事务控制
*/
@Transactional(
readOnly = false, // 读写事务
timeout = -1, // 事务的超时时间不限制
noRollbackFor = ArithmeticException.class, // 遇到数学异常不回滚
isolation = Isolation.DEFAULT, // 事务的隔离级别,数据库的默认
propagation = Propagation.REQUIRED // 事务的传播行为
)
public void save(Dept dept) {
logDao.insertLog(); // 保存日志 【自己开启一个事务】
int i = 1/0;
deptDao.save(dept); // 保存部门
}
}
|
//测试:日志传播行为
@Repository
public class LogDao {
@Resource
private JdbcTemplate jdbcTemplate;
// 始终开启事务
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void insertLog() {
jdbcTemplate.update("insert into log_ values(‘dept.....‘)");
}
}
|
<!-- 1.数据源对象: c3p0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///hib_demo"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
<property name="initialPoolSize" value="3"></property>
<property name="maxPoolSize" value="10"></property>
<property name="maxStatements" value="100"></property>
<property name="acquireIncrement" value="2"></property>
</bean>
<bean class="haust.vk.b_anno.DeptDao"></bean>
<!-- JdbcTemplate 工具类实例 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事务管理器类 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 开启注解扫描 -->
<context:component-scan base-package="haust.vk.b_anno"></context:component-scan>
<!-- 注解方式实现事务: 指定注解方式实现事务 -->
<tx:annotation-driven transaction-manager="txManager"/>
|
public class App {
@Test
public void testApp() throws Exception {
ApplicationContext ac=new ClassPathXmlApplicationContext("haust/vk/b_anno/bean.xml");
//模拟数据
Dept dept= new Dept();
dept.setDeptName("测试 : 开发部");
DeptService deptService = (DeptService) ac.getBean("deptService");
deptService.save(dept);
}
// 了解容器的相关方法
@Test
public void testApp2() throws Exception {
//1. 根据bean.xml配置路径,创建容器对象
//ApplicationContext ac = new ClassPathXmlApplicationContext("cn/itcast/b_anno/bean.xml");
//2. 根据多个配置文件的路径,创建容器对象
//ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{});
//3. 容器对象相关方法
ApplicationContext ac =
new ClassPathXmlApplicationContext("haust/vk/b_anno/bean.xml");
//3.1 从容器中获取指定名称的bean对象
//DeptDao deptDao = (DeptDao) ac.getBean("deptDao");
//3.2 根据类型从容器获取实例 【该类型只能在IOC中有唯一的对象,否则报错】
//DeptDao deptDao = ac.getBean(DeptDao.class);
//3.3 泛型,不需要强转
//DeptDao deptDao = ac.getBean("deptDap", DeptDao.class);
//3.4 获取容器中bean对象的数量
//int count = ac.getBeanDefinitionCount();
String[] names = ac.getBeanDefinitionNames();
System.out.println(Arrays.toString(names));
}
}
|
标签:
原文地址:http://www.cnblogs.com/viakiba/p/5698165.html