spring探索

本文详细介绍了Spring框架的核心概念,包括对象创建的方式、Bean的配置、单例与多例的区别、延迟加载机制以及初始化和销毁的过程。此外还深入探讨了Spring AOP编程,包括手动实现AOP的方式和AOP配置等。
创建对象的两种方式(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("提交事务事务");

    }

}  
  1. import java.lang.reflect.InvocationHandler;
  2. import java.lang.reflect.Method;
  3. import java.lang.reflect.Proxy;
  4.  
  5. publicclassProxyFactory{
  6. privatestaticObject target;
  7. privatestaticAop aop;
  8.  
  9. publicstaticObject getProxyInstance(Object target_,Aop aop_){
  10. target=target_;
  11. aop=aop_;
  12.  
  13. returnProxy.newProxyInstance(
  14. target.getClass().getClassLoader(),
  15. target.getClass().getInterfaces(),
  16. newInvocationHandler(){
  17.  
  18. @Override
  19. publicObject invoke(Object proxy,Method method,Object[] args)
  20. throwsThrowable{
  21. aop.begin();
  22.  
  23. Object returnValue = method.invoke(target, args);
  24.  
  25. aop.commit();
  26.  
  27.  
  28. return returnValue;
  29. }
  30. });
  31. }
  32. }

 

    <!-- 开启注解扫描 -->

    <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>  
  1. importstatic org.junit.Assert.*;
  2.  
  3. import org.junit.Test;
  4. import org.springframework.context.ApplicationContext;
  5. import org.springframework.context.support.ClassPathXmlApplicationContext;
  6. publicclassApp{
  7. ApplicationContext ac=newClassPathXmlApplicationContext("haust/vk/d_myaop1/bean.xml");
  8. @Test
  9. publicvoid testMyaop()throwsException{
  10. IUserDao dao=(IUserDao) ac.getBean("userDao_proxy");
  11. System.out.println(dao.getClass());
  12. dao.save();
  13. }
  14.  
  15. }

 

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()) &amp;&amp; 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));

    }

}


 

转载于:https://my.oschina.net/viakiba/blog/748386

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值