Java - 静态代理java静态代理和动态代理
代理的名词
代理对象:增强后的对象
目标对象:被增强的对象
Java代理-静态代理
静态代理包含继承和聚合两种。
1. 继承
代理对象继承目标对象,重写需要增强的方法。
public interface UserDao {void query();
}import org.springframework.stereotype.Service;
@Service
public class UserDaoImpl implements UserDao {
@Override
public void query() {
System.out.println("query db");
}
}public class UserDaoLogImpl extends UserDaoImpl {
@Override
public void query() {
System.out.println("start to query");
super.query();
System.out.println("end to query");
}
}public class TestApp {
public static void main(String[] args) {
UserDaoImpl dao2 = new UserDaoLogImpl();
dao2.query();
}
}
`UserDaoLogImpl`是代理对象,`UserDaoImpl`是目标对象。
代理对象与目标对象时相对的,会根据情况发生变化。`UserDaoLogImpl`以后也会成为目标对象。
2. 聚合
import com.merckgroup.msizing.domain.service.UserDao;public class UserDaoOperateImpl implements UserDao {
UserDao userDao;
public UserDaoOperateImpl(UserDao userDao) { // 装饰者模式
this.userDao = userDao;
}
@Override
public void query() {
System.out.println("operate - start to query");
userDao.query();
System.out.println("operate - end to query");
}
}public class TestApp {
public static void main(String[] args) {
UserDao targetUserDao = new UserDaoImpl();
UserDaoOperateImpl userDaoOperate = new UserDaoOperateImpl(targetUserDao);
userDaoOperate.query();
}
}
运行结果:
operate - start to queryquery db
operate - end to query
添加时间代理
public class UserDaoTimeImpl implements UserDao {UserDao userDao;
public UserDaoTimeImpl(UserDao userDao) { // 装饰者模式
this.userDao = userDao;
}
@Override
public void query() {
System.out.println("time - start to query");
userDao.query();
System.out.println("time - end to query");
}
}
案例
代理1:对日志代理。A
代理2:对操作代理。B
代理3:对时间代理。C
需求:实现对时间和操作的代理。
需求-方案1:采用链式继承,继承B时添加时间代理,继承C时添加操作代理。(继承)
需求-方案2:采用聚合方式
方案1:比较容易实现
方案2:实例代码
public class UserDaoTimeImpl implements UserDao {UserDao userDao;
public UserDaoTimeImpl(UserDao userDao) { // 装饰者模式
this.userDao = userDao;
}
@Override
public void query() {
System.out.println("time - start to query");
userDao.query();
System.out.println("time - end to query");
}
}public class UserDaoOperateImpl implements UserDao {
UserDao userDao;
public UserDaoOperateImpl(UserDao userDao) { // 装饰者模式
this.userDao = userDao;
}
@Override
public void query() {
System.out.println("operate - start to query");
userDao.query();
System.out.println("operate - end to query");
}
}public class TestApp {
public static void main(String[] args) {
UserDao target = new UserDaoTimeImpl(new UserDaoImpl()); // 对时间
UserDao userDaoLog = new UserDaoOperateImpl(target); // 继而对操作
userDaoLog.query();
}
}
运行结果:
operate - start to querytime - start to query
query db
time - end to query
operate - end to query
结论:使用静态代理时会产生类,继而可能引发类爆炸(继承与聚合皆是如此)。因此,在不确定时尽量减少使用静态代理。
不确定情况:不明确后续的扩展情况,是否需要扩展接口或者扩展接口的程度如何。