Spring框架簡介⑦
接下來進入Spring的另一核心AOP(aspect oriented programming)
面向切面程式設計, 通過預編譯的方式在執行期通過動態代理實現的一種技術, AOP是OOP的延續, 利用AOP可以實現業務和切面的邏輯分離. 降低耦合度, 程式的重用性提高.
1 JDK動態代理
JDK動態代理的目標是介面實現類的形式
直接上程式碼:
代理類:
package com.rl.spring.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JDKProxy implements InvocationHandler {
private Object targetObj;
/**
* 第一個引數: 獲得目標物件的類的載入器
* 第二個引數: 獲得目標物件的介面
* 第三個引數: 設定回撥物件, 當前代理物件(也就是UserServiceImpl)的方法(save方法)被呼叫時, 會委派該引數去呼叫invoke
需要傳入InvocationHandler的子類, 這裡用this指代JDKProxy
* @return
*/
public Object createProxyInstance(Object targetObj) {
this.targetObj = targetObj;
return Proxy.newProxyInstance(this.targetObj.getClass().getClassLoader(),
this.targetObj.getClass().getInterfaces(), this);
}
/**
* proxy: 代理類
* Method: 要呼叫的業務方法
* Object[]: 呼叫的業務方法的引數
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 獲得目標物件的get方法
Method getMeth = this.targetObj.getClass().getMethod("getUser", null);
// 通過反射來呼叫getUser
Object user = getMeth.invoke(targetObj, null);
Object obj = null;
if (user != null) {
// 業務方法返回的值
obj = method.invoke(this.targetObj, args);
} else {
System.out.println("您還沒有登入");
}
return obj;
}
}
測試類:
package com.rl.spring.test;
import org.junit.Test;
import com.rl.spring.model.User;
import com.rl.spring.proxy.JDKProxy;
import com.rl.spring.service.UserService;
import com.rl.spring.service.impl.UserServiceImpl;
public class TestSpring {
@Test
public void Test() {
UserServiceImpl ui = new UserServiceImpl();
ui.setUser(new User());
//通過業務介面來接收代理物件
UserService userService = (UserService) new JDKProxy().createProxyInstance(ui);
System.out.println(userService.getClass());
userService.save();
}
}
UserServiceImpl類
package com.rl.spring.service.impl;
import com.rl.spring.model.User;
import com.rl.spring.service.UserService;
public class UserServiceImpl implements UserService {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public void save() {
System.out.println("儲存使用者...");
}
@Override
public void update() {
System.out.println("修改使用者...");
}
}
輸出:
儲存使用者.../ 如果在測試程式碼中沒有new User()的話, 則提示"您還沒有登入!"
小總結:
代理類提供了一種切面針對目標物件的一種攔截並做相應處理, 在User類中並沒有邏輯處理, 但卻能夠實現一種攔截判斷是否有登入的效果, 這就是代理類的功能所在.
2 CGLIB動態代理
CGLIB可以對普通類做動態代理, 前提是目標類不能為final, 類裡面的方法也不能為final
直接上程式碼:
代理類:
package com.rl.spring.proxy;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
public class CGLIBProxy implements MethodInterceptor {
private Object targetObj;
public Object createProxyInstance(Object targetObj) {
this.targetObj = targetObj;
Enhancer en = new Enhancer();
en.setSuperclass(this.targetObj.getClass());
en.setCallback(this);
return en.create();
}
@Override
public Object intercept(Object arg0, Method method, Object[] arg2, MethodProxy arg3) throws Throwable {
Method getMeth = this.targetObj.getClass().getMethod("getUser", null);
Object user = getMeth.invoke(targetObj, null);
Object obj = null;
if(user != null) {
obj = method.invoke(this.targetObj, arg2);
}else {
System.out.println("您還沒有登入!");
}
return obj;
}
}
測試程式碼:
package com.rl.spring.test;
import org.junit.Test;
import com.rl.spring.model.User;
import com.rl.spring.proxy.CGLIBProxy;
import com.rl.spring.proxy.JDKProxy;
import com.rl.spring.service.UserService;
import com.rl.spring.service.impl.UserServiceImpl;
public class TestSpring {
@Test
public void Test1() {
UserServiceImpl ui = new UserServiceImpl();
ui.setUser(new User());
UserServiceImpl userServiceImpl = (UserServiceImpl) new CGLIBProxy().createProxyInstance(ui);
System.out.println(userServiceImpl.getClass());
userServiceImpl.save();
}
}
目標物件(UserServiceImpl同上, 不列出來了), 該類可作為實現類, 也可作為普通類 CGLIB都可以對其做動態代理
相關文章
- Spring框架簡介⑩Spring框架
- Spring框架簡介⑨Spring框架
- Spring框架簡介⑧Spring框架
- Spring框架簡介⑥Spring框架
- Spring框架簡介⑤Spring框架
- Spring框架簡介④Spring框架
- Spring框架簡介③Spring框架
- Spring框架簡介②Spring框架
- Spring框架簡介①Spring框架
- Spring 簡介Spring
- HTML 框架簡介HTML框架
- Scrapy框架簡介框架
- SpringMVC框架簡介②SpringMVC框架
- SpringMVC框架簡介①SpringMVC框架
- Hibernate框架簡介⑤框架
- Hibernate框架簡介④框架
- Hibernate框架簡介③框架
- Hibernate框架簡介②框架
- Hibernate框架簡介①框架
- spring框架的介紹Spring框架
- Spring Batch 簡介SpringBAT
- Spring框架之IOC介紹Spring框架
- [轉]SSH框架簡介框架
- Spring(2)-AOP簡介Spring
- Spring_Framework_簡介SpringFramework
- Spring系列.Bean簡介SpringBean
- Spring常用Annotation簡介Spring
- uni-app 框架簡介APP框架
- Flutter路由框架Fluro簡介Flutter路由框架
- wsgiref模組、web框架、django框架簡介Web框架Django
- Spring Security中AuthorizationManager簡介Spring
- Spring AOP基礎簡介Spring
- Spring中雲事件簡介Spring事件
- Spring Cloud Gateway使用簡介SpringCloudGateway
- Spring 框架基礎(06):Mvc架構模式簡介,執行流程詳解Spring框架MVC架構模式
- Spring框架系列(2) - Spring簡單例子引入Spring要點Spring框架單例
- 工作流框架Flowable 簡介框架
- OSX 攻擊框架Empyre簡介框架