spring框架的二大主要的功能就是IOC和AOP。java
IOC: 控制反轉(依賴注入) web
AOP: 面向切面編程 spring
介紹spring 中的註解的使用,xml配置等目前在市面上面較少。編程
首先介紹Java自帶的元註解 (元註解就是 能註解到註解上的註解,能用在其餘註解上的註解 )數組
session
用於描述註解的範圍,即註解在哪用。它說明了Annotation所修飾的對象範圍:Annotation可被用於 packages、types(類、接口、枚舉、Annotation類型)、類型成員(方法、構造方法、成員變量、枚舉值)、方法參數和本地變量(如循環變量、catch參數)等。取值類型(ElementType) app
CONSTRUCTOR:用於描述構造器
FIELD:用於描述域即類成員變量
LOCAL_VARIABLE:用於描述局部變量
METHOD:用於描述方法
PACKAGE:用於描述包
PARAMETER:用於描述參數
TYPE:用於描述類、接口(包括註解類型) 或enum聲明
TYPE_PARAMETER:1.8版本開始,描述類、接口或enum參數的聲明
TYPE_USE:1.8版本開始,描述一種類、接口或enum的使用聲明
eg :
public @interface Log {
......
}
用於描述註解的生命週期,表示須要在什麼級別保存該註解,即保留的時間長短。取值類型RetentionPolicy)框架
SOURCE:在源文件中有效(即源文件保留)
CLASS:在class文件中有效(即class保留)
RUNTIME:在運行時有效(即運行時保留)
eg:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
......
}
用於描述其它類型的annotation應該被做爲被標註的程序成員的公共API,所以能夠被例如javadoc此類的工具文檔化。它是一個標記註解,沒有成員。 ide
eg :
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
......
}
用於表示某個被標註的類型是被繼承的。若是一個使用了@Inherited修飾的annotation類型被用於一個class,則這個annotation將被用於該class的子類。 工具
在註解配置中經常使用的啓動方法就是:
<!--在XML中啓用方法-->
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
Person bean = (Person) applicationContext.getBean("person");
System.out.println(bean);
--------------------------------------------------------------------------
<!--在註解中啓用方法-->
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
Person bean = applicationContext.getBean(Person.class);
System.out.println(bean);
getBeanNamesForType:獲得當前IOC容器加載進來的bean的名稱
String[] namesForType = applicationContext.getBeanNamesForType(Person.class);
for (String name : namesForType) {
System.out.println(name);
}
組件,沒有明確的角色
在業務邏輯層使用(service層)
在數據訪問層使用(dao層)
在展示層使用,控制器的聲明(Controller)
注入ioc容器中,默認是以方法的名稱做爲注入容器裏面的名稱,需注意@bean能夠不在配置類裏面使用,不過通過@Bean註解使用過的方法所在的類也會被加載到ioc容器裏面。
//配置類==配置文件
告訴Spring這是一個配置類,用在一個類的上面,配置類
@Configuration == <bean id="person" class="com.opendev.entity.Person"></bean>
value:指定要掃描的包,用在配置類上面,告訴程序在spring中的掃包範圍
掃描多個包還有提供掃包的自定義掃包規則
package com.atguigu.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.ComponentScans;
import com.atguigu.bean.Person;
//配置類==配置文件
//告訴Spring這是一個配置類
(
value = {
value="com.atguigu",includeFilters = { (
/*@Filter(type=FilterType.ANNOTATION,classes={Controller.class}),
@Filter(type=FilterType.ASSIGNABLE_TYPE,classes={BookService.class}),*/
type=FilterType.CUSTOM,classes={MyTypeFilter.class}) (
},useDefaultFilters = false)
}
)
//@ComponentScan value:指定要掃描的包
//excludeFilters = Filter[] :指定掃描的時候按照什麼規則排除那些組件
//includeFilters = Filter[] :指定掃描的時候只須要包含哪些組件
//FilterType.ANNOTATION:按照註解
//FilterType.ASSIGNABLE_TYPE:按照給定的類型;
//FilterType.ASPECTJ:使用ASPECTJ表達式
//FilterType.REGEX:使用正則指定
//FilterType.CUSTOM:使用自定義規則
public class MainConfig {
//給容器中註冊一個Bean;類型爲返回值的類型,id默認是用方法名做爲id
"person")//聲明瞭注入ioc容器裏面的對象爲person,默認都是以方法名做爲id (
public Person person01(){
return new Person("lisi", 20);
}
}
//類中組件統一設置。知足當前條件,這個類中配置的全部bean註冊才能生效;
裏面須要寫上相應接口的實現類
導入組件,id默認是組件的全類名
默認是單實例的
//默認是單實例的
/**
* ConfigurableBeanFactory#SCOPE_PROTOTYPE
* @see ConfigurableBeanFactory#SCOPE_SINGLETON
* @see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST request
* @see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION sesssion
* @return\
* @Scope:調整做用域
* prototype:多實例的:ioc容器啓動並不會去調用方法建立對象放在容器中。
* 每次獲取的時候纔會調用方法建立對象;
* singleton:單實例的(默認值):ioc容器啓動會調用方法建立對象放到ioc容器中。
* 之後每次獲取就是直接從容器(map.get())中拿,
* request:同一次請求建立一個實例
* session:同一個session建立一個實例
*
* 懶加載:
* 單實例bean:默認在容器啓動的時候建立對象;
* 懶加載:容器啓動不建立對象。第一次使用(獲取)Bean建立對象,並初始化;
*
*/
//@Scope("prototype")
"person") (
public Person person(){
System.out.println("給容器中添加Person....");
return new Person("張三", 25);
}
/**
* bean的生命週期:
* bean建立---初始化----銷燬的過程
* 容器管理bean的生命週期;
* 咱們能夠自定義初始化和銷燬方法;容器在bean進行到當前生命週期的時候來調用咱們自定義的初始化和銷燬方法
*
* 構造(對象建立)
* 單實例:在容器啓動的時候建立對象
* 多實例:在每次獲取的時候建立對象\
*
* BeanPostProcessor.postProcessBeforeInitialization
* 初始化:
* 對象建立完成,並賦值好,調用初始化方法。。。
* BeanPostProcessor.postProcessAfterInitialization
* 銷燬:
* 單實例:容器關閉的時候
* 多實例:容器不會管理這個bean;容器不會調用銷燬方法;
*
*
* 遍歷獲得容器中全部的BeanPostProcessor;挨個執行beforeInitialization,
* 一但返回null,跳出for循環,不會執行後面的BeanPostProcessor.postProcessorsBeforeInitialization
*
* BeanPostProcessor原理
* populateBean(beanName, mbd, instanceWrapper);給bean進行屬性賦值
* initializeBean
* {
* applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
* invokeInitMethods(beanName, wrappedBean, mbd);執行自定義初始化
* applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
*}
*
*
*
* 1)、指定初始化和銷燬方法;
* 經過@Bean指定init-method和destroy-method;
* 2)、經過讓Bean實現InitializingBean(定義初始化邏輯),
* DisposableBean(定義銷燬邏輯);
* 3)、可使用JSR250;
* @PostConstruct:在bean建立完成而且屬性賦值完成;來執行初始化方法
* @PreDestroy:在容器銷燬bean以前通知咱們進行清理工做
* 4)、BeanPostProcessor【interface】:bean的後置處理器;
* 在bean初始化先後進行一些處理工做;
* postProcessBeforeInitialization:在初始化以前工做
* postProcessAfterInitialization:在初始化以後工做
*
* Spring底層對 BeanPostProcessor 的使用;
* bean賦值,注入其餘組件,@Autowired,生命週期註解功能,@Async,xxx BeanPostProcessor;
*
*
*
*/
/**
* 自動裝配;
* Spring利用依賴注入(DI),完成對IOC容器中中各個組件的依賴關係賦值;
*
* 1)、@Autowired:自動注入:
* 1)、默認優先按照類型去容器中找對應的組件:applicationContext.getBean(BookDao.class);找到就賦值
* 2)、若是找到多個相同類型的組件,再將屬性的名稱做爲組件的id去容器中查找
* applicationContext.getBean("bookDao")
* 3)、@Qualifier("bookDao"):使用@Qualifier指定須要裝配的組件的id,而不是使用屬性名
* 4)、自動裝配默認必定要將屬性賦值好,沒有就會報錯;
* 可使用@Autowired(required=false);
* 5)、@Primary:讓Spring進行自動裝配的時候,默認使用首選的bean;
* 也能夠繼續使用@Qualifier指定須要裝配的bean的名字
* BookService{
* @Autowired
* BookDao bookDao;
* }
*
* 2)、Spring還支持使用@Resource(JSR250)和@Inject(JSR330)[java規範的註解]
* @Resource:
* 能夠和@Autowired同樣實現自動裝配功能;默認是按照組件名稱進行裝配的;
* 沒有能支持@Primary功能沒有支持@Autowired(reqiured=false);
* @Inject:
* 須要導入javax.inject的包,和Autowired的功能同樣。沒有required=false的功能;
* @Autowired:Spring定義的; @Resource、@Inject都是java規範
*
* AutowiredAnnotationBeanPostProcessor:解析完成自動裝配功能;
*
* 3)、 @Autowired:構造器,參數,方法,屬性;都是從容器中獲取參數組件的值
* 1)、[標註在方法位置]:@Bean+方法參數;參數從容器中獲取;默認不寫@Autowired效果是同樣的;都能自動裝配
* 2)、[標在構造器上]:若是組件只有一個有參構造器,這個有參構造器的@Autowired能夠省略,參數位置的組件仍是能夠自動從容器中獲取
* 3)、放在參數位置:
*
* 4)、自定義組件想要使用Spring容器底層的一些組件(ApplicationContext,BeanFactory,xxx);
* 自定義組件實現xxxAware;在建立對象的時候,會調用接口規定的方法注入相關組件;Aware;
* 把Spring底層一些組件注入到自定義的Bean中;
* xxxAware:功能使用xxxProcessor;
* ApplicationContextAware==》ApplicationContextAwareProcessor;
*
*
*
*
*/