spring體系結構
主要api
BeanFactoy 一個工廠,用於生成任意Bean,負責讀取bean配置文檔,管理bean的加載,實例化,維護bean之間的依賴關係,負責bean的聲明週期。特點是延遲加載,只有在第一次getBean時纔會初始化Bean
ApplicatinContext:是他的子接口,功能更加強大,當配置文件被加載,Bean就被初始化。
提供了國際化處理
資源訪問:Resource rs = ctx.getResource(”classpath:config.properties”)
“file:c:/config.properties”
事件傳遞:通過實現ApplicationContextAware接口
Bean自動裝配
各層Context實現:WebApplicationContextUtils
ClassPathXmlApplicationContext 加載classpath下的配置文件
FileSystemXmlApplicationContext 用於加載指定盤符下的xml
Bean的種類
1.普通Bean: < bean id=”” class=”A”> ,spring直接創建A實例,並返回
2.FactoryBean:是一個特殊的bean,具有工廠生成對象能力,只能生成特定的對象。bean必須使用 FactoryBean接口,此接口提供方法 getObject() 用於獲得特定bean。< bean id=”” class=”FB”> 先創建FB實例,使用調用getObject()方法,並返回方法的返回值,FB fb = new FB();return fb.getObject();例如:ProxyFactoryBean是生成代理Bean的。
作用域
生命週期
初始化和銷燬的方法是在目標方法執行前後執行的
1 . 在xml中定義Bean
2 . 在xml中配置初始化和銷燬
package com.spring.lifecycle;
public class BookServiceImpl implements BookService {
@Override
public void insert() {
System.out.println("調用dao");
}
public void init(){
System.out.println("初始化");
}
public void destroy(){
System.out.println("銷燬");
}
}
<!-- init-method 初始化方法名稱 destory-mothod 銷燬方法名稱 -->
<bean id="BookService" class="com.spring.lifecycle.BookServiceImpl"
init-method="init" destroy-method="destroy"></bean>
3 . 調用bean
package com.spring.lifecycle;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestApi {
@Test
public void fun(){
String xmlPath="com/spring/lifecycle/applicationContext.xml";
ClassPathXmlApplicationContext context= new ClassPathXmlApplicationContext(xmlPath);
BookService service = context.getBean("BookService",BookService.class);
service.insert();
context.close();
}
}
4 .Bean的銷燬
注意的是:銷燬Bean必須是單例的,並且一定要關閉容器。
BeanPostProcessor
spring 提供一種機制,只要實現此接口BeanPostProcessor,並將實現類提供給spring容器,spring容器將自動執行,在初始化方法前執行before(),在初始化方法後執行after() 生成代理類,AOP的底層實現。
執行的流程:
問題:如果我們要使用jdk動態代理來實現 對目標方法的增強,是應該在before() 還是After()中返回代理對象那?我們的初始化和銷燬的方法都是在接口的實現類中定義的。而我們的接口中只有目標方法,假如我們要在before()中實現代理。那麼在執行初始化方法的時候用的就是代理對象,而代理對象沒有這個方法導致無法初始化。所以要在接口中也實現初始化和銷燬的方法。或者在After()方法中返回代理對象。這也正好說明了JDK動態代理沒有擺脫接口的限制,所有就有了cglib代理。
package com.spring.lifecycle;
public interface BookService {
void insert();
}
package com.spring.lifecycle;
public class BookServiceImpl implements BookService {
@Override
public void insert() {
System.out.println("調用dao");
}
public void init(){
System.out.println("初始化");
}
public void destroy(){
System.out.println("銷燬");
}
}
package com.spring.lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("before");
System.out.println(beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("after");
System.out.println(beanName);
return new ProxyService().bind(bean);
}
}
package com.spring.lifecycle;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyService implements InvocationHandler {
private Object target;// 真實對象
public Object bind(Object obj) {
this.target = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("開啓事務");
Object object = method.invoke(this.target, args);
System.out.println("關閉事務");
return object;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- init-method 初始化方法名稱 destory-mothod 銷燬方法名稱 -->
<bean id="BookService" class="com.spring.lifecycle.BookServiceImpl"
init-method="init" destroy-method="destroy"></bean>
<!-- 綁定bean -->
<bean class="com.spring.lifecycle.MyBeanPostProcessor"></bean>
</beans>