- Java code
/** * 单例模式,通过DBPool连接池获取数据库连接 * @author shi */public class JdbcUtils { private static Logger logger = Logger.getLogger(JdbcUtils.class); //简单的数据库连接池 private static DataSource dataSource = new DBPool(); private static JdbcUtils instance; //构造函数私有化,为实现单例 private JdbcUtils() { } //注意:"锁"的方式,以及第二次"null"的判断(仔细思考:若两个线程同时到达) public static JdbcUtils getInstance() { if(instance == null) { synchronized (JdbcUtils.class) { if(instance == null) { instance = new JdbcUtils(); } } } logger.info("成功获取JdbcUtils实例"); return instance; } //返回连接Connection public Connection getConnetion() throws SQLException { return dataSource.getConnection(); } //释放资源 public void free(ResultSet rs, Statement st, Connection conn) { try { if(rs != null) rs.close(); } catch (SQLException e) { throw new JdbcException(e.getMessage()); } finally { try { if(st != null)st.close(); } catch (SQLException e) { throw new JdbcException(e.getMessage()); } finally { try { if(conn != null) conn.close(); } catch (SQLException e) { throw new JdbcException(e.getMessage()); } } } } }----------------------------------------/** * 数据库连接池 * @author shi */public class DBPool{ private static Logger logger = Logger.getLogger(DBPool.class); private static LinkedList<Connection> connectionPool; private static int currentCount; private Selec
上面是利用动态代理的一个小例子。但“动态代理”的内部机制是怎样实现的呢?还是通过“反射”吗?请大家指点。
------解决方案--------------------
- Java code
我做了个测试 调用ProxyGenerator.generateProxyClass(proxyName, interfaces);方法得到字节码 写到文件中(.class文件) 然后通过JD反编译 得到代理类(.java文件)这个类是这样的public final class MyProxyClass extends Proxy implements MyInterface有一个构造方法public MyProxyClass(InvocationHandler paramInvocationHandler) throws { super(paramInvocationHandler); }所以我们通常用动态代理是这么用的:写一个类,比如名字叫MyHandler,实现InvocationHandler接口.然后把MyHandler对象作为参数传给Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);这个方法.这个方法会调用ProxyGenerator.generateProxyClass(proxyName, interfaces);方法生成一个代理类.然后通过反射调用上面那个构造方法进行实例化,参数就是自己写的MyHandler的对象.而这个代理类的任何方法实际上都是调用这个MyHandler的invoke方法,只是不同方法的参数不同.所以无论你调用什么方法,实际上都在调用你写的invoke方法.这样你就可以在invoke方法里自由发挥,前插后插,随便你怎么插,这就是AOP.
------解决方案--------------------