创建对象的两种方式(spring):
//现在,把对象的创建交给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容器对象【用实现类,因为要调用销毁的方法】
//得到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();
Bean 配置:
1) 对象创建: 单例/多例
* scope="singleton", 默认值, 即 默认是单例 【service/dao/工具类】
* scope="prototype", 多例; 【Action对象】
*
2) 什么时候创建?
* scope="prototype" 在用到对象的时候,才创建对象。
* scope="singleton" 在启动(容器初始化之前), 就已经创建了bean,且整个应用只有一个。
3)是否延迟创建
* lazy-init="false"默认为false, 不延迟创建,即在启动时候就创建对象
* lazy-init="true"延迟初始化, 在用到对象的时候才创建对象
* (只对单例有效)
4) 创建对象之后,初始化/销毁
* init-method="init_user" 【对应对象的init_user方法,在对象创建爱之后执行 】
* destroy-method="destroy_user" 【在调用容器对象的destriy方法时候执行,(容器用实现类)】
struts-spring练习:
在此练习中,主要记住的2点:
一:web.xml的spring配置:
<!-- 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>
二:对于上述spring的配置,bean-*.xml的书写
hibernate362文件夹
自动加载,此工程使用set对象赋值和处理依赖关系。
代理:
静态代理:
// 接口 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(); } } |
以及spring中的cglib代理
Cglib 代理,也叫做子类代理。在内存中构建一个子类对象从而实现对目标对象功能的扩展。 可以代理没有继承接口的类
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(); } } |
AOP切面编程
手动实现aop编程1:
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(); } } |
手动实现aop编程2:
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> |
|
aop相关的基本配置:
注解方式
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> </beans> |
//指定当前类为切面类 @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);
} } |
aop配置xml方式
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(); } } |
expression="execution(* haust.vk.f_aop_xml.*.*(..))"
<?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>
spring的jdbc使用
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; } } } |
事务
xml方式:
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)); } } |