zoukankan      html  css  js  c++  java
  • 仿hibernate,spring框架手动写

    近期学习了hibernate底层技术和spring 的底层技术,认为非常不错,所以想分享下吐舌头吐舌头,要是说的不够具体。能够去下载资源自己查看下载链接

    技术的体现是在实际中的。如今大体介绍一下吧

    首先介绍hibernate手动写:

    仿HIBERNATE

    hibernate是属于DAO,专门又来管理数据的,connection中还要考虑多线程的情况。同一个线程还要必需要是同样的connection对象。这就需要ThreadLocal来实 现。

    1,connection考虑须要多线程,须要採用多例模式来实现,

    2。读取配置文件,如真的hibernate中的配置文件(自己写的仅仅有mysqld的)

    3,当须要进行事物处理的时,须要採用同一个connection对象。须要用到ThreadLocal对象进行设置

    4。当connection关闭时,而不是直接关闭,仅仅是将其还回线程池中。

    详细代码呈上:


    <span style="font-size: 18px;">
    /*
     * 我们须要採用线程池避免线程冲突。多例模式----》获得时候须要上锁
     * pool中的数量是有限的,我们採用了代理模式,改动 con.close(),将连接换回来
     * 为了保证统一线程是一个用户,我们採用threadlocal本地线程技术
     */
    public class hibernateFactory2 {
    	private static final int NUM=3;
    	private static List<Connection> pool =new ArrayList<Connection>();
    	</span><strong><span style="font-size:24px;color:#cc0000;"><u>private static  ThreadLocal<Connection> t=new ThreadLocal<Connection>();//声明本地线程、</u></span></strong><span style="font-size: 18px;">
    	static{
    	</span><span style="color:#cc0000;font-size: 18px;">	<strong><u>//读取配置文件</u></strong>
    		Properties p =new Properties();
    		</span><span style="font-size: 18px;">
    			try {
    				p.load(hibernateFactory2.class.getClassLoader().getResourceAsStream("jdbc.properties"));
    				//读取里面的值,一直改动配置文件就可以
    				String driver=p.getProperty("driver");
    				String url=p.getProperty("url");
    				String user=p.getProperty("username");
    				String password=p.getProperty("password");
    				//System.out.println(driver+url+user+password);
    				Class.forName(driver);
    				for(int i=0;i<NUM;i++){
    					final Connection	con=DriverManager.getConnection(url, user, password);
    					</span><span style="color:#cc0000;font-size: 18px;"><strong><em><u>//採用动态代理開始进行对connection接口实现代理,对con.close,实现换回去</u></em></strong>
    					Object o =Proxy.newProxyInstance(hibernateFactory2.class.getClassLoader(), new Class[]{Connection.class},
    							new InvocationHandler() {
    								
    								@Override
    								public Object invoke(Object proxy, Method method, Object[] args)
    										throws Throwable {
    									if(method.getName().equals("close")){
    										pool.add((Connection)(proxy));
    										System.out.println("换回来了。。

    "); return null; } return method.invoke(con, args); } }); pool.add((Connection)o);</span><span style="font-size: 18px;"> } // System.out.println("初始化完成"+con); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static synchronized Connection getCon() throws Exception{ /* * <span style="color:#ff0000;"><strong><em>把自己主动会到一个它所维护的那个map中去取,把以“当前线程对象”为key所相应的那个value取出来</em></strong></span> */ Connection c=t.get(); if(c==null){ while(pool.size()<=0){ System.out.println("池中已经乜有连接"); Thread.sleep(1000); } c=pool.remove(0);//为事物处理方便了。当出现错误的时候,多表一个都不能存储。採用一个connection t.set(c); } return c; } } </span>


    仿Spring

    这一层基本上进行的是业务逻辑处理
    1,刚開始时候,将事务处理写在这一层。可是对于单个的函数的。每个须要写。代码太繁琐了,所以直接将从servlet转到service的时候(切面技术),採用代理模式代理一下,在代理模式里面,我们採用进行事物处理,须要的我们拦截进行事物处理。不须要的。我们直接放行,做他自己的事情。

        2,在使用代理模式的时候。为了让外面注入不须要强转。proxy里面採用了泛型的引入。

    详细代码呈上:

    public class Tx implements InvocationHandler{
    	private Object srcobj;
    	private Object returnValue;
    	public Tx(Object srcobj) {
    		this.srcobj=srcobj;
    	}
    	<span style="color:#cc0000;"><strong>//这里写的是通用版本号,代理模式</strong></span>
    	//这个须要强转。所以引入了以下的那个不须要强转
    //	public static Object getProxy(Object srcobj){
    //		Object o =Proxy.newProxyInstance(
    //				Tx.class.getClassLoader(), 
    //				srcobj.getClass().getInterfaces(),
    //				new Tx(srcobj));
    //		return o;
    //	}
    	/*
    	 *<strong> 以下这个是升级版本号,返回的类型不用强转</strong>
    	 */
    	public static<T> T getProxy(Object srcobj){
    		Object o =Proxy.newProxyInstance(
    				Tx.class.getClassLoader(), 
    				srcobj.getClass().getInterfaces(),
    				new Tx(srcobj));
    		return (T)o;
    	}
    
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args)
    			throws Throwable {
    		//全部的代理在这里開始
    			Connection con=null;
    		
    			<u><strong><span style="color:#ff0000;">if(method.isAnnotationPresent(MyTrans.class)){//这里採用注解的方式来差别是都须要进行事物处理</span></strong></u>
    				System.out.println("被拦截了");
    				try { 
    				 con =hibernateFactory2.getCon();
    				 con.setAutoCommit(false);
    				 returnValue=method.invoke(srcobj, args);//调用被代理的自己去运行
    				 con.commit();
    				System.out.println("事物提交成功");
    			} catch (Exception e) {
    				try {
    					System.out.println("回滚了"+e.getMessage());
    					con.rollback();
    				}catch (SQLException e1) {
    					throw  new RuntimeException("回滚失败"+e.getMessage());
    				}
    			}finally{
    				try {
    					con.setAutoCommit(true);
    					con.close();//这里关闭,是还回池中,採用代理模式改动过
    				}catch (SQLException e) {
    					throw new RuntimeException("关闭数据库连接失败11"+e.getMessage());
    				}
    			}
    			
    		}else{
    			System.out.println("不拦截,放行!

    。"); return method.invoke(srcobj, args); } return returnValue; } }


    这是自己写的注解类

    package cn.hncu.publs.tx;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Retention(RetentionPolicy.RUNTIME)//作用于执行时,默认在编译器
    @Target(value=ElementType.METHOD)//作用于方法
    public @interface MyTrans {
    }

    源码已上传下载链接

    欢迎各位大神指点吐舌头



  • 相关阅读:
    cuda基础----流
    cuda基础---异步并行执行
    cuda基础---cuda通信机制
    cuda基础-----cuda编程模型/软件体系/存储器模型
    大顶堆 小顶堆应用----中位数查找
    Maven配置阿里云镜像
    C++中bool型变量按位取反总是为true
    区分C++的继承、覆盖、隐藏、重载
    C++Primer第5章 语句
    C++Primer第4章 表达式
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7216853.html
Copyright © 2011-2022 走看看