Spring设计模式,事务管理和代理模式的应用

扩充:贝叶斯定理答案见底。

设计模式对关于面向对象问题的具体解决方案.

1,单例多例

在设计单例模式时,要注意两个点

1.构造方法要私有

2.成员变量要私有

3.创建对象所用的方法要被synchronized修饰.(因为方法体中会涉及到判断当前成员对象是否为空,在饿汉模式下,会有多个线程来访问该方法,为了防止判断访问结果同时为空,从而创建多个对象,就要被synchronized修饰)

2,模版

所谓模板板式,就是在父类中定义算法的主要流程,而把一些个性化的步骤延迟到子类中去实现,父类始终控制着整个流程的主动权,子类只是辅助父类实现某些可定制的步骤

父类

public abstract class FatherClass {

    //人生
    public final void 人生(){
        学习();
        工作();
        爱情();
    }

    //学习
    public void 学习(){
        System.out.println("=========放学回家学到晚上12点不许睡觉===========");
    }

    //工作
    public void 工作(){
        System.out.println("============稳定就好===============");
    }

    //爱情(放飞自我)
    public abstract void 爱情();



}

继承父类的类

package com.apesource.test;
//儿子
public class SonClass extends FatherClass{



    @Override
    public void 学习() {
        System.out.println("=========开心就好,及格万岁============");
    }


    @Override
    public void 爱情() {
        System.out.println("======肤白貌美大长腿.....=======");
    }
}

如果该方法被重写,那么结果是子类的内容。反之,则是父类的内容 

  •  Spring中jdbcTemplate、hibernateTemplate等以Template结尾的
  •  对数据库操作的类,它们就使用到模板模式。一般情况下,我们都是使用继承的方式来实现模板模式,但是Spring并没有使用这种方式,而是使用Callback模式与模板方法配合,既达到了代码复用的效果,同时增加了灵活性。

3,工厂

一个工厂可以根据传入参数的不同,而创建出来不同的对象。

4,代理(静态代理,动态代理)

 功能:
        1.中介隔离作用
        2.方法增强

一.静态代理,静态代理中,代理在代码执行前已经被创建出来了。

动态代理,是代码执行的时候被创建出来的, 1.基于接口(jdk自带)2.基于子类(第三方)

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.InvocationHandler;子类

public class Test03 {
    public static void main(String[] args) {
        //1.创建被代理对象
        ISinger teng = new TengEr();
        //2.创建代理对象
        ISinger jinJiRen = (ISinger)Enhancer.create(teng.getClass(), new InvocationHandler() {
            @Override
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {

                Object obj = method.invoke(teng,objects);

                return obj;
            }
        });

        //3.使用
        jinJiRen.sing();


    }
}

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; 

public class Test02 {
    public static void main(String[] args) {
        //1.被代理对象
        ISinger zhouJieLun = new ZhouJieLun();
        /**
         * 2.创建代理对象
         * ClassLoader loader被代理对象的类的加载器
         * Class[] interfaces,被代理对象的类的字节数组
         * InvocationHandler h处理器对象
         * */
        ISinger jinJiRen = (ISinger) Proxy.newProxyInstance(zhouJieLun.getClass().getClassLoader(), zhouJieLun.getClass().getInterfaces(), new InvocationHandler() {
            /**
             * Object proxy, 被代理对象的引用
             * Method method,被代理对象类中的所有方法
             * Object[] args 被代理对象类中的所有方法的参数
             * Object 被代理对象类中的所有方法的返回值
             *
             * */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //方法增强
                System.out.println("挑一个舞,打个球~~~");

                Object obj = method.invoke(zhouJieLun,args);//执行周杰伦唱歌方法,(执行被代理对象中的所有方法)

                return obj;
            }
        });

        //3.消费使用
        jinJiRen.sing();


    }
}

 

事务管理

1,在转账服务时,更新数据库时,可能会发生异常,就会导致金额不对

解决方法,1.被调用到的dao层语句,都拿着同一个对象,这个对象可以实现锁的功能。那么就要在dao层query和update语句中,增加一个Connection对象。threadLocal可以充当sql语句的锁对象

因为threadlocal有一个线程们的公共区域,完全可以实现当公共区有一个connection的时候,线程们完全不需要再考虑在去造很多connection。

ThreadLocal叫做线程变量,意思是ThreadLocal中填充的变量属于当前线程,该变量对其他线程而言是隔离的,也就是说该变量是当前线程独有的变量。ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。

2.service层中,调用事务管理,当异常发生时,实现事务的回滚

①在dao层用到的连接工具类

package com.apesource.util;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * @author  * @version 1.0
 * @since 2023/9/15
 */
public class ConnectionUtil {

    //1.线程区域对象
    ThreadLocal threadLocal =  new ThreadLocal();
    //2.数据源
    private DataSource dataSource;
    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }
    Connection connection = null;

    //获取连接
    public Connection createConn(){
        try {
            //1.线程区域
            connection = threadLocal.get();
            //2.判断
            if (connection ==null){
                //创建连接
                connection = dataSource.getConnection();
                //保存
                threadLocal.set(connection);
            }
            return connection;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return null;
    }

    //关闭连接
    public void closeConn(){
        threadLocal.remove();//解除绑定
    }
}

在dao层的每一个语句都装配工具类 

 //装配连接工具类
    ConnectionUtil connectionUtil;

    public void setConnectionUtil(ConnectionUtil connectionUtil) {
        this.connectionUtil = connectionUtil;
    }

    @Override
    public void save(Student student) {
        try {
            queryRunner.update(connectionUtil.createConn(),"insert into student(sname,shobby,smoney) value(?,?,?)",student.getSname(),student.getShobby(),student.getSmoney());
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

②在service层用到的事务管理工具类

package com.apesource.util;

import java.sql.SQLException;

/**
 * @author 
 * @version 1.0
 * @since 2023/9/15
 */
public class TransactionUtil {
    //装配连接工具类
    ConnectionUtil connectionUtil;

    public void setConnectionUtil(ConnectionUtil connectionUtil) {
        this.connectionUtil = connectionUtil;
    }

    //开启事务
    public void beginTransaction(){
        try {
            connectionUtil.createConn().setAutoCommit(false);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
    //提交事务
    public void commitTransaction(){
        try {
            connectionUtil.createConn().commit();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
    //回滚事务
    public void rollbackTransaction(){
        try {
            connectionUtil.createConn().rollback();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
    //关闭事务
    public void closeTransaction(){
        try {
            connectionUtil.createConn().close();//关闭连接
            connectionUtil.closeConn();//解除绑定
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}

service里的用到的事务管理

   @Override
    public void transfer(String sourceName, String targetName, int money) {
        try {
            //开启事务
            transactionUtil.beginTransaction();
            //1.查询用户信息
            Student sourceStudent =  dao.findByName(sourceName);
            Student targetStudent =  dao.findByName(targetName);
            //2.java代码中实现转账
            sourceStudent.setSmoney(sourceStudent.getSmoney()-money);
            targetStudent.setSmoney(targetStudent.getSmoney()+money);
            //3.修改数据库
            dao.update(sourceStudent);
            int a = 10/0;//模拟异常
            dao.update(targetStudent);
            //提交事务
            transactionUtil.commitTransaction();
        } catch (Exception e) {
            e.printStackTrace();
            //回滚事务
            transactionUtil.rollbackTransaction();
        }finally {
            //关闭事务
            transactionUtil.closeTransaction();
        }
    }

                                                                      优化方法

优化方法

采用Beanfactory创建代理对象,代理对象可以用来方法增强,可以将被代理对象的方法不经过污染,就可以实现事务管理。

在这个案例中,controller是消费者

 
   
       
   

   
    proxySerivce" class="com.apesource.service.StudentServiceImp" factory-bean="factory" factory-method="createProxy">
   
       
       
   

   
   
        studentService" ref="proxySerivce">
   

抽取方法用到了代理对象 ,BeansFactory代码如下:

package com.apesource.factory;

import com.apesource.service.IStudentService;
import com.apesource.util.TransactionUtil;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author 
 * @version 1.0
 * @since 2023/9/15
 */
public class BeansFactory {

    //装配被代理业务对象
    IStudentService toProxyService;

    public void setToProxyService(IStudentService toProxyService) {
        this.toProxyService = toProxyService;
    }

    //装配事务工具类
    TransactionUtil transactionUtil;

    public void setTransactionUtil(TransactionUtil transactionUtil) {
        this.transactionUtil = transactionUtil;
    }

    //创建代理对象
    public IStudentService createProxy(){
      return (IStudentService)Proxy.newProxyInstance(toProxyService.getClass().getClassLoader(), toProxyService.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                Object obj = null;//主业务方法
                try {
                    transactionUtil.beginTransaction();
                    obj = method.invoke(toProxyService,args);
                    transactionUtil.commitTransaction();
                } catch (Exception e) {
                    e.printStackTrace();
                    transactionUtil.rollbackTransaction();
                } finally {
                    transactionUtil.closeTransaction();
                }
                return obj;
            }
        });
    }
}

八年后的重逢:贝叶斯定理是一则随机事件的条件概率(或边缘概率)的定理,其中P(A|B)是在B发生的情况下A发生的可能性。也就是说,如果你喜欢他,那么他就会喜欢你。如果你对他好,他也会对你好的。因此,如果你表白,你需要相信他,将全部的情感完全吐露给对方,将真诚当成一生的信念,投入到爱情中,去充实彼此的关系,全心全意地去经营彼此的关系,将相互接纳、宽容、体谅和支持当作最可贵的宝贵财富。 

你可能感兴趣的:(Spring,spring,设计模式,java)