JDK动态代理
UserDao
1 2 3 4 5 6 7 8
| package com.course.dao;
public interface UserDao1 {
public void addUser(String userName); public void deleteUser(Integer userId); }
|
1 2 3 4 5 6
| package com.course.dao;
public interface UserDao2 {
public void queryUser(Integer userId); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| package com.course.dao.impl;
import com.course.dao.UserDao1; import com.course.dao.UserDao2;
public class UserDaoImpl implements UserDao1, UserDao2 {
@Override public void addUser(String userName) { System.out.println("Save user, userName = " + userName); }
@Override public void deleteUser(Integer userId) { System.out.println("delete user, userId = " + userId); }
@Override public void queryUser(Integer userId) { System.out.println("query user, user[userId=" + userId + ", userName=Jerry]"); } }
|
DepartmentDao
1 2 3 4 5 6
| package com.course.dao;
public interface DepartmentDao {
public void addDepartmentDao(); }
|
1 2 3 4 5 6 7 8 9 10 11 12
| package com.course.dao.impl;
import com.course.dao.DepartmentDao;
public class DepartmentDaoImpl implements DepartmentDao {
@Override public void addDepartmentDao() { System.out.println("Save department");
} }
|
ProxyFactory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| package com.course.proxy;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy;
public class ProxyFactory {
private Object targetObject; public ProxyFactory(Object targetObject) { this.targetObject = targetObject; }
public Object getProxyInstance() {
Object proxyObject = Proxy.newProxyInstance( targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), new InvocationHandler() {
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { openTransaction(); Object invoke = method.invoke(targetObject, args); commitTransaction(); return invoke; } }); return proxyObject; } public void openTransaction() { System.out.println("open transaction"); } public void commitTransaction() { System.out.println("commit transaction"); } }
|
测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| package com.course.test;
import com.course.dao.DepartmentDao; import com.course.dao.UserDao1; import com.course.dao.UserDao2; import com.course.dao.impl.DepartmentDaoImpl; import com.course.dao.impl.UserDaoImpl; import com.course.proxy.ProxyFactory;
public class Test {
public static void main(String[] args) { UserDaoImpl userDaoImpl = new UserDaoImpl(); ProxyFactory userDaoProxyFactory = new ProxyFactory(userDaoImpl); UserDao1 userDaoProxy1 = (UserDao1) userDaoProxyFactory.getProxyInstance(); UserDao2 userDaoProxy2 = (UserDao2) userDaoProxyFactory.getProxyInstance(); String userName = "Tom"; userDaoProxy1.addUser(userName);
Integer userId = 1; userDaoProxy1.deleteUser(userId);
userId = 2; userDaoProxy2.queryUser(userId);
DepartmentDao departmentDao = new DepartmentDaoImpl(); ProxyFactory departmentDaoProxyFactory = new ProxyFactory(departmentDao); DepartmentDao departmentDaoProxy = (DepartmentDao) departmentDaoProxyFactory.getProxyInstance(); departmentDaoProxy.addDepartmentDao();
} }
|
总结
优点:有了目标对象,只要通过代理工厂就可以为所有的目标对象去创建代理对象,不用显式创建代理对象了。
缺点:目标对象必须至少实现一个接口,代理对象强制类型转换时只能转换为目标对象所实现的接口类型
原理:当调用Proxy.newProxyInstance方法时,系统会根据目标对象的类加载器和目标对象所实现的所有接口,在内存里创建一个实现了目标对象所有接口的代理类,并使用这个代理类创建了一个代理对象并返回。