代理对象(proxy) 增强后的对象
目标对象(target) 被增强的对象
1.静态代理(继承和聚合)
继承:代理对象继承目标对象,重写需要增强的方法;缺点:会代理类过多,非常复杂
聚合:目标对象和代理对象实现同一个接口,代理对象当中要包含目标对象。缺点:也会产生类爆炸,只不过比
继承少一点点
总结:如果在不确定的情况下,尽量不要去使用静态代理。因为一旦你写代码,就会产生类,一旦产生类就爆炸。
2.动态代理(jdk和cglib)
JDK动态代理:
cglib动态代理:
静态代理-继承(eg:在原功能之前添加日志,权限功能)(根据顺序不同目标对象和代理对象也不同)
public class UserDao {
public void queryAll() {
System.out.println("=== query -> db -> queryAll ===");
//1 改代码 添加日志业务逻辑 添加 权限业务逻辑
}
}
test
public class Test {
public static void main(String[] args) {
UserDao dao = new UserDao();
dao.queryAll();
//2 改代码 添加日志业务逻辑 添加 权限业务逻辑
}
}
为了不破坏类的封装性,使用代理技术扩展功能
扩展日志功能
public class LogUserDao extends UserDao{
@Override
public void queryAll() {
System.out.println("=== query -> db -> queryAll log===");
super.queryAll();
}
}
public class Test {
public static void main(String[] args) {
UserDao dao = new LogUserDao();
dao.queryAll();
}
}
控制台打印实现了日志功能
=== query -> db -> queryAll log===
=== query -> db -> queryAll ===
同理像这样扩展权限功能
public class PermissionUserDao extends UserDao{
@Override
public void queryAll() {
System.out.println("=== query -> db -> queryAll Permission===");
super.queryAll();
}
}
public class Test {
public static void main(String[] args) {
UserDao dao = new PermissionUserDao();
dao.queryAll();
}
}
控制台打印
=== query -> db -> queryAll Permission===
=== query -> db -> queryAll ===
如果需要两个一起呢,虽然语法不支持多继承,但是我们可以链式继承
public class LogAndPerUserDao extends LogUserDao{
@Override
public void queryAll() {
System.out.println("=== query -> db -> queryAll Permission ===");
//如果是继承LogUserDao 就写权限逻辑 具体看先后顺序
//如果是继承PermissionUserDao 就写日志逻辑
super.queryAll();
}
}
public class Test {
public static void main(String[] args) {
UserDao dao = new LogAndPerUserDao();
dao.queryAll();
}
}
控制台打印
=== query -> db -> queryAll Permission ===
=== query -> db -> queryAll log===
=== query -> db -> queryAll ===
可以发现每次都要新建一个类
静态代理-聚合(接口)
public interface UserDao {
public void queryAll();
}
public class UserDaoImpl implements UserDao{
@Override
public void queryAll() {
System.out.println("=== query -> db -> queryAll ===");
}
}
public class Test {
public static void main(String[] args) {
UserDao userDao = new UserDaoImpl();
userDao.queryAll();
}
}
控制台打印
=== query -> db -> queryAll ===
扩展功能日志
public class ProxyLogUserDaoImpl implements UserDao{
UserDao userDao;
public ProxyLogUserDaoImpl(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void queryAll() {
System.out.println("=== query -> db -> queryAll log===");
userDao.queryAll();
}
}
public class Test {
public static void main(String[] args) {
UserDao userDao = new UserDaoImpl();//目标对象
ProxyLogUserDaoImpl proxyLogUserDaoImpl = new ProxyLogUserDaoImpl(userDao);//代理对象
proxyLogUserDaoImpl.queryAll();
}
}
控制台打印
=== query -> db -> queryAll log===
=== query -> db -> queryAll ===
权限同理
public class ProxyPermissionUserDaoImpl implements UserDao{
UserDao userDao;
public ProxyPermissionUserDaoImpl(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void queryAll() {
System.out.println("=== query -> db -> queryAll Permission ===");
userDao.queryAll();
}
}
public class Test {
public static void main(String[] args) {
UserDao userDao = new UserDaoImpl();
//ProxyLogUserDaoImpl proxyLogUserDaoImpl = new ProxyLogUserDaoImpl(userDao);
//proxyLogUserDaoImpl.queryAll();
ProxyPermissionUserDaoImpl proxyPermissionUserDaoImpl = new ProxyPermissionUserDaoImpl(userDao);
proxyPermissionUserDaoImpl.queryAll();
}
}
控制台打印
=== query -> db -> queryAll Permission ===
=== query -> db -> queryAll ===
扩展日志和权限功能
public class Test {
public static void main(String[] args) {
UserDao userDao = new UserDaoImpl();
ProxyLogUserDaoImpl proxyLogUserDaoImpl = new ProxyLogUserDaoImpl(userDao);
ProxyPermissionUserDaoImpl proxyPermissionUserDaoImpl = new ProxyPermissionUserDaoImpl(proxyLogUserDaoImpl);
proxyPermissionUserDaoImpl.queryAll();
}
}
控制台打印
=== query -> db -> queryAll Permission ===
=== query -> db -> queryAll log===
=== query -> db -> queryAll ===
同样如果一直有不同的新功能需要扩展,我们只能不停的新建接口去代理实现
下篇-动态代理