Spring IOC和aop的原理及實(shí)例詳解
這篇文章主要介紹了Spring IOC和aop的原理及實(shí)例詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
Spring是一個輕量級的控制反轉(zhuǎn)(IoC)和面向切面(AOP)的容器框架。特點(diǎn)是面向接口編程,松耦合。
1:IOC(控制反轉(zhuǎn)) 別名(DI:依賴注入)
首先來一段ioc的實(shí)現(xiàn)原來代碼:
public class ClassPathXmlApplicationContext implements BeanFactory {
private Map<String , Object> beans = new HashMap<String, Object>();
//IOC Inverse of Control DI Dependency Injection
public ClassPathXmlApplicationContext() throws Exception {
SAXBuilder sb=new SAXBuilder();
//解析xml配置文件
Document doc=sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml"));
Element root=doc.getRootElement(); //獲取根元素
List list=root.getChildren("bean");//根元素下的子元素
for(int i=0;i<list.size();i++) {
Element element=(Element)list.get(i);
String id=element.getAttributeValue("id");
String clazz=element.getAttributeValue("class");
Object o = Class.forName(clazz).newInstance(); //反射獲得實(shí)例
System.out.println(id);
System.out.println(clazz);
beans.put(id, o);
//注入bean屬性
for(Element propertyElement : (List<Element>)element.getChildren("property")) {
String name = propertyElement.getAttributeValue("name"); //userDAO
String bean = propertyElement.getAttributeValue("bean"); //u
Object beanObject = beans.get(bean);//UserDAOImpl instance
String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
System.out.println("method name = " + methodName);
Method m = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]);
m.invoke(o, beanObject);
}
}
}
public Object getBean(String id) {
return beans.get(id);
}
}
//xml文件 <beans> <bean id="u" class="com.bjsxt.dao.impl.UserDAOImpl" /> <bean id="userService" class="com.bjsxt.service.UserService" > <property name="userDAO" bean="u"/> </bean> </beans>
以上代碼實(shí)現(xiàn)了將UserDAOImpl注入到userService.
值得注意的是:以上操作都是spring幫我們實(shí)現(xiàn)的,我們只需要理解如何配置即可。
spring還提供了bean的生存周期和范圍屬性:
scope:singleton(單例,即每次調(diào)用的對象都為同一個)。 prototype(原型,即以bean對象為原型,每次new一個新對象出來)
init-method="init" destroy-method="destroy" lazy-init="true"(延遲初始化bean,即spring啟動時,不初始化bean,當(dāng)需要使用時才實(shí)例化,作用:但spring啟動緩慢時可使用)
現(xiàn)在基本都是用注解實(shí)現(xiàn),但只要能明白spring是如何實(shí)現(xiàn)bean的注入,基本原理都是一樣的。spring在中間的作用就是幫我們實(shí)現(xiàn)元素之前的注入,誰注入到誰就需要用到不同的注解了。
AOP(切面編程)
首先還是先來一段代碼
定義一個InvocationHandler的實(shí)現(xiàn)類
public class UserServiceTest {
@Test
public void testAdd() throws Exception {
BeanFactory applicationContext = new ClassPathXmlApplicationContext();
UserService service = (UserService)applicationContext.getBean("userService");
User u = new User();
u.setUsername("zhangsan");
u.setPassword("zhangsan");
service.add(u);
}
@Test
public void testProxy() {
UserDAO userDAO = new UserDAOImpl();
LogInterceptor li = new LogInterceptor();
li.setTarget(userDAO);
UserDAO userDAOProxy = (UserDAO)Proxy.newProxyInstance(userDAO.getClass().getClassLoader(), userDAO.getClass().getInterfaces(), li);
userDAOProxy.delete();
userDAOProxy.save(new User());
}
調(diào)用測試類,service和DAO實(shí)現(xiàn)類沒有貼出來,就是打印一句話出來表現(xiàn)方法執(zhí)行了。
public class LogInterceptor implements InvocationHandler {
private Object target;
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
public void beforeMethod(Method m) {
System.out.println(m.getName() + " start");
}
@Override
public Object invoke(Object proxy, Method m, Object[] args)
throws Throwable {
beforeMethod(m);
m.invoke(target, args);
return null;
}
}
以上代碼簡單的實(shí)現(xiàn)了一個動態(tài)代理,并執(zhí)行了自己的一段邏輯。
那么aop是如何實(shí)現(xiàn)切面編程的呢,就是通過動態(tài)代理。當(dāng)然這也是spring來實(shí)現(xiàn)的,而我們需要做的就是知道如何編寫編織語法。
- JoinPoint:切入點(diǎn)
- PointCut: 切入點(diǎn)的集合
- Aspect:切面
- Advice: 相當(dāng)于Aspect的before
- Around:周圍,環(huán)繞(需要帶參數(shù)ProceedingJoinPoint jp)
需要注意的是:被產(chǎn)生代理的對象需要現(xiàn)實(shí)接口spring才能產(chǎn)生代理對象,默認(rèn)使用java se 中的 InvocationHandler 和 proxy 兩個類產(chǎn)生代理對象,若沒有實(shí)現(xiàn)接口,則需要另外引入一個jar包(cglib-nodep-2.1_3.jar);他是通過二進(jìn)流的方式產(chǎn)生代理對象。
那么spring 幫我們做了什么?
1:充分利用java se 中的反射機(jī)制幫助我們對對象的注入,即 IOC,
2: 也是java se 中的動態(tài)代理幫助我們實(shí)現(xiàn) 切面編程,當(dāng)然我們也需要熟悉一下asceptj 的切入語法。這就是aop。
所以這里可以總結(jié)一下,java se 的特點(diǎn)有反射,動態(tài)代理,(這里面必然會用到多態(tài),動態(tài)綁定)
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
java 分轉(zhuǎn)元與元轉(zhuǎn)分實(shí)現(xiàn)操作
這篇文章主要介紹了java 分轉(zhuǎn)元與元轉(zhuǎn)分實(shí)現(xiàn)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02
SpringMVC @GetMapping注解路徑?jīng)_突問題解決
MD5對密碼進(jìn)行加密存儲是常見的一種加密方式,本文主要介紹了Java雙重MD5加密實(shí)現(xiàn)安全登錄,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
java rocketmq--消息的產(chǎn)生(普通消息)
這篇文章主要介紹了java rocketmq--消息的產(chǎn)生(普通消息),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,,需要的朋友可以參考下2019-06-06
java序列化與ObjectOutputStream和ObjectInputStream的實(shí)例詳解
這篇文章主要介紹了java序列化與ObjectOutputStream和ObjectInputStream的實(shí)例詳解的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下2017-09-09
SpringBoot2.0 整合 SpringSecurity 框架實(shí)現(xiàn)用戶權(quán)限安全管理方法
Spring Security是一個能夠?yàn)榛赟pring的企業(yè)應(yīng)用系統(tǒng)提供聲明式的安全訪問控制解決方案的安全框架。這篇文章主要介紹了SpringBoot2.0 整合 SpringSecurity 框架,實(shí)現(xiàn)用戶權(quán)限安全管理 ,需要的朋友可以參考下2019-07-07
Java 實(shí)現(xiàn)完整功能的學(xué)生管理系統(tǒng)實(shí)例
讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用Java實(shí)現(xiàn)一個完整版學(xué)生管理系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平2021-11-11

