靜態代理:自己定義的代理類;
動態代理:程序在運行時生成。
一、靜態代理:
接口:UserManager:對用戶的增刪改查。
1 package com.dwr.spring.proxy;
2
3 public interface UserManager {
4 public void addUser(String username,String password);
5 public void deleteUser(int userid);
6 public void modifyUser(int userid,String username,String password);
7 public void findUser(int userid);
8 }
實現類:UserManagerImpl:
1 package com.dwr.spring.proxy;
2
3 public class UserManagerImpl implements UserManager {
4 @Override
5 public void addUser(String username, String password) {
6 System.out.println("--------UserManagerImpl.addUser()----------");
7 }
8
9 @Override
10 public void deleteUser(int userid) {
11 System.out.println("--------UserManagerImpl.deleteUser()----------");
12 }
13
14 @Override
15 public void modifyUser(int userid, String username, String password) {
16 System.out.println("--------UserManagerImpl.modifyUser()----------");
17 }
18
19 @Override
20 public void findUser(int userid) {
21 System.out.println("--------UserManagerImpl.findUser()----------");
22 }
客戶端類:調用方法;
1 package com.dwr.spring.proxy;
2
3 public class Client {
4
5 public static void main(String[] args){
6 UserManager userManager = new UserManagerImpl();
7 userManager.addUser("Jack","123456");
8 }
9 }
結果:
1 --------UserManagerImpl.addUser()----------
結果正常顯示。
在UserManagerImpl中加入安全性檢測:
1 public void checkSecurity(){ 2 System.out.println("--------UserManagerImpl.checkSecurity()----------"); 3 }
UserManagerImpl中每個方法都要調用該方法,耦合度提高。使用代理實現類實現該功能:
在代理中:必須要有要控制對象的引用;
將安全檢測方法放到代理類中。調用每個方法前進行安全檢測,對原有的類的結構並沒有破壞,也完成了需求。
UserManagerImplProxy類:
1 package com.dwr.spring.proxy;
2
3 public class UserManagerImplProxy implements UserManager {
4 private UserManager userManager;
5
6 public UserManagerImplProxy(UserManager userManager){
7 this.userManager = userManager;
8 }
9
10 public void checkSecurity(){
11 System.out.println("--------UserManagerImpl.checkSecurity()----------");
12 }
13
14 @Override
15 public void addUser(String username, String password) {
16 checkSecurity();
17 this.userManager.addUser(username,password);
18 }
19
20 @Override
21 public void deleteUser(int userid) {
22 checkSecurity();
23 this.userManager.deleteUser(userid);
24 }
25
26 @Override
27 public void modifyUser(int userid, String username, String password) {
28 checkSecurity();
29 this.userManager.modifyUser(userid,username,password);
30 }
31
32 @Override
33 public void findUser(int userid) {
34 checkSecurity();
35 this.userManager.findUser(userid);
36 }
37 }
客戶端測試:
1 package com.dwr.spring.proxy;
2
3 public class Client {
4
5 public static void main(String[] args){
6 //使用靜態代理模式實現
7 UserManager userManager = new UserManagerImplProxy(new UserManagerImpl());
8 userManager.addUser("Jack","123456");
9 }
10 }
靜態代理模式使我們自己寫的,若接口中方法很多,就會很麻煩,這時就需采用AOP來處理!!!
二、動態代理:
既然是動態代理模式就不需要UserManagerImplProxy這個代理類了。
需要聲明一個類實現InvocationHandler接口,並定義一個newProxy的方法返回動態代理
1 package com.dwr.spring.proxy;
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Method;
5 import java.lang.reflect.Proxy;
6
7 public class SecurityHandler implements InvocationHandler {
8 private Object targetObject;
9
10 public Object newProxy(Object targetObject){
11 this.targetObject = targetObject;
12 //返回動態代理
13 return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(),this);
14 }
15
16
17 public void checkSecurity(){
18 System.out.println("--------UserManagerImpl.checkSecurity()----------");
19 }
20
21 @Override
22 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
23 checkSecurity();
24 Object ret = null;
25
26 try {
27 //調用目標對象的真實方法,將返回值保存在ret中
28 ret = method.invoke(this.targetObject, args);
29 } catch (Exception e){
30 e.printStackTrace();
31 }
32 return ret;
33 }
34 }
客戶端測試:
1 SecurityHandler securityHandler = new SecurityHandler();
2 UserManager userManager = (UserManager) securityHandler.newProxy(new UserManagerImpl()); //創建代理對象
3 userManager.addUser("Tom","123456");
結果:
1 --------UserManagerImpl.checkSecurity()---------- 2 --------UserManagerImpl.addUser()----------
使用動態代理想進行安全檢測就進行安全檢測;不想檢測就不檢測,就是這麼任性。。。
客戶端:
1 package com.dwr.spring.proxy;
2
3 public class Client {
4
5 public static void main(String[] args){
6 SecurityHandler securityHandler = new SecurityHandler();
7 UserManager userManager = (UserManager) securityHandler.newProxy(new UserManagerImpl());//進行了安全檢測
8 userManager.addUser("Tom","123456");
9 System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++");
10 UserManager userManager1 = new UserManagerImpl(); //沒有進行安全檢測
11 userManager1.addUser("Lily","123456");
12 }
13 }
結果:
--------UserManagerImpl.checkSecurity()----------
--------UserManagerImpl.addUser()----------
++++++++++++++++++++++++++++++++++++++++++++++++++
--------UserManagerImpl.addUser()----------
使用CGLib實現:
創建一個類實現MethodInterceptor接口,重寫intercept方法:當代理對象的方法被調用時會調用該方法!!
CGlibProxyFactory類:
1 package com.dwr.spring.proxy;
2
3 import org.springframework.cglib.proxy.Enhancer;
4 import org.springframework.cglib.proxy.MethodInterceptor;
5 import org.springframework.cglib.proxy.MethodProxy;
6
7 import java.lang.reflect.Method;
8
9 public class CGlibProxyFactory implements MethodInterceptor {
10
11 private Object targetObject;
12
13 public Object newProxy(Object targetObject){
14 this.targetObject = targetObject;
15 Enhancer enhancer = new Enhancer();
16 enhancer.setSuperclass(this.targetObject.getClass());
17 enhancer.setCallback(this);
18 //返回代理對象
19 return enhancer.create();
20 }
21
22 public void checkSecurity(){
23 System.out.println("--------UserManagerImpl.checkSecurity()----------");
24 }
25
26 /**
27 * @param proxy 帶來的對象本身
28 * @param method 被攔截到的方法
29 * @param objects 方法的參數
30 * @param methodProxy 方法的代理對象
31 */
32 @Override
33 public Object intercept(Object proxy, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
34 checkSecurity();
35 Object ret = null;
36
37 try {
38 ret = method.invoke(this.targetObject, objects);
39 } catch (Exception e){
40 e.printStackTrace();
41 }
42 return ret;
43 }
44 }
測試:
1 package com.dwr.spring.proxy;
2
3 public class CGlibProxyTest {
4
5 public static void main(String[] args){
6 CGlibProxyFactory factory = new CGlibProxyFactory();
7 UserManagerImpl userManager = (UserManagerImpl) factory.newProxy(new UserManagerImpl());
8 userManager.addUser("Tom","123456");
9 }
10 }
結果:
--------UserManagerImpl.checkSecurity()----------
--------UserManagerImpl.addUser()----------