本质:是一种包装设计模式;
在不修改源码的情况下,增强(重写)一个方法实现。
代码
1、创建接口NameNode
public interface NameNode {
public void method1(String t);
public void method2(String t1,String t2);
public void method3();
}
2、接口实现类NameNodeImpl
public class NameNodeImpl implements NameNode {
@Override
public void method1(String t) {
System.out.println("我是method1"+t);
}
@Override
public void method2(String t1,String t2) {
System.out.println("我是method2"+t1+t2);
}
@Override
public void method3() {
System.out.println("我是method3");
}
}
3、创建代理对象
import java.lang.reflect.*;
public class DFSClient {
public static void main(String[] args) {
//真实对象
NameNode nameNode = new NameNodeImpl();
//生成代理对象
NameNode proxy = (NameNode) Proxy.newProxyInstance(DFSClient.class.getClassLoader(),//获得类加载器
nameNode.getClass().getInterfaces(), //真实对象实现的接口
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
if (methodName.equals("method1")){
System.out.println("代理调用menthod1"+args[0]);
}else if (methodName.equals("method2")){
System.out.println("代理调用menthod2"+args[0]+args[1]);
}else {
method.invoke(nameNode,args);
}
return null;
}
});
proxy.method1("熊爱明");
proxy.method2("小米","销毁");
}
}
经典案例:数据库连接池
1、安装MySQL
https://blog.csdn.net/qq_45335413/article/details/106957967
登录MySQL:mysql -uroot -p
2、MySQL数据库的配置:
创建一个新的数据库:create database hive;
创建一个新的用户:
create user ‘hiveowner’@’%’ identified by ‘Welcome_1’;
给该用户授权
grant all on hive.* TO ‘hiveowner’@’%’;
grant all on hive.* TO ‘hiveowner’@‘localhost’ identified by ‘Welcome_1’;
3、Java代码实现
先导入jdbc的jar包
(1)、继承DataSource接口,继承关系“是is”,聚合关系“有has”
public class MyDataSource implements DataSource {
//注册驱动器
public static String driver = "com.mysql.jdbc.Driver";
//指明URL
public static String url = "jdbc:mysql://192.168.92.130:3306/hive?useSSL=false";
//指明用户
public static String user = "hiveowner";
//指明密码
public static String password = "Welcome_1";
//存储connection
public static LinkedList<Connection> list = new LinkedList<Connection>();
// 设置静态代码块
static {
try {
//注册驱动
Class.forName(driver);
//获取连接
for (int i = 0; i < 10; i++) {
Connection connection = DriverManager.getConnection(url, user, password);
list.add(connection);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public Connection getConnection() throws SQLException {
//判断是否还有连接
if (list.size() > 0){
Connection con = list.removeFirst();
Connection proxy = (Connection) Proxy.newProxyInstance(MyDataSource.class.getClassLoader(),
con.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodname = method.getName();
if (methodname.equals("close"))
{
list.addLast(con);
System.out.println("已经归还对象");
return null;
}else {
return method.invoke(con,args);
}
}
});
return proxy;
}else {
throw new SQLException("系统正在繁忙,请稍后......");
}
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
return null;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return null;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
}
@Override
public int getLoginTimeout() throws SQLException {
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
}
(2)创建Mian函数,连接数据库,当然在这里不能直接链接数据库,需要连接我们创建的数据库连接池
public class MyTestDataSource {
public static void main(String[] args) throws SQLException {
DataSource ds = new MyDataSource();
for (int i = 0; i < 11; i++) {
Connection connection = ds.getConnection();
System.out.println("获取到第" + i +"个链接:" + connection);
connection.close();
}
}
}