這一段純屬廢話,能夠不用看........,兌現諾言,每週寫一篇博客。最近除了學習算法,還有想更全面瞭解Spring框架的使用。因而開始了個人學習之旅。因爲本人工做中接觸的是一個很是很是老的項目,因此對Spring的瞭解僅僅停留在一些基本的使用上。爲加深瞭解Spring提供的功能,因而就果斷買了《Spring實戰》,初略看下來,收穫仍是有的,但總感受也不是特別特別優秀的書。接下來,我就來談談我對Spring的一點淺薄理解。web
對於Java後端開發來講,Spring基本是再熟悉不過的框架了,甚至能夠說,如今不用Spring框架進行開發的JAVA後端項目應該基本是百裏挑一(我的猜想)。相信一提到Spring,你們想到的就是DI(Dependency Injection)/IOC(Inversion of Control)、AOP這些名詞了,沒錯,這就是Spring提供的核心功能。DI、IOC說的就是同一個功能,翻譯過來分別是依賴注入、控制反轉,其實就是咱們把對象的建立、銷燬、維護交給Spring,讓它幫咱們管理這些對象,但咱們須要的時候,讓它直接給咱們一個,不須要咱們本身去new。AOP就是面向切面編程。額額,看着這些名詞一臉懵逼.................................算法
接下來就來個小例子看看這到底能幹嗎,能給咱們編程提供什麼樣的幫助。。spring
在給小例子以前咱們得先了解兩個概念:apache
一、既然要讓Spring幫咱們建立管理對象、那咱們就得先告訴Spring怎麼去建立這些對象,還有對象之間是什麼關係。Spring提供了3個方案來實現:一、XML中顯式配置。二、Java中顯式配置。三、自動包掃描編程
二、Spring提供了倆種容器類型,分別爲BeanFactory、ApplicationContext。BeanFactory只提供了基本的DI支持,ApplicationContext基於BeanFactory構建,能提供更多服務。後端
Spring上下文,就是一種容器,繼承自ApplicationContext,提供更多功能,如常見的,bash
AnnotationConfigApplicationContext可從JAVA配置類中加載上下文app
ClassPathXmlApplicationContext 從類路徑下的XML文件中加載上下文。框架
FileSystemXmlApplilcationContext 從文件系統路徑中加載上下文maven
例子
接下來咱們用Idea編輯器,經過maven工具建立一個maven項目來體驗下Spring。建立完以後咱們首先要引入Spring jar包,經過maven,咱們不須要本身去下載,只須要在配置文件中配置咱們須要用到的jar包。項目結構以下圖
以後咱們在pom.xml文件中配置須要用到的jar文件,咱們將spring的幾個核心包配置進來。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.springstudy</groupId>
<artifactId>luckyspring</artifactId>
<version>1.0-SNAPSHOT</version>
<name>luckyspring</name>
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<!-- spring 版本 -->
<org.springframework.version>4.0.0.RELEASE</org.springframework.version>
</properties>
<dependencies>
<!-- 當前項目用到的3個核心spring jar包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${org.springframework.version}</version>
</dependency
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
複製代碼
如今假設咱們有一個公司,一個公司裏面得有僱員來工做,才能讓公司提供服務,因而咱們建立僱員類
package cn.springstudy.vo;
public class Employee {
public void work(){
System.out.println("Employ start to Work");
};
}複製代碼
再建立公司類
package cn.springstudy.vo;
public class Company {
//公司類有個僱員對象
private Employee employee;
public void supportService(){
employee.work();
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
}複製代碼
前面咱們說過告訴Spring怎麼去建立對象有三種方式
<?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">
<!-- 配置一個對象 指定該對象id爲emplayee-->
<bean id="employee" class="cn.springstudy.vo.Employee"></bean>
<!--配置對象,以後往對象中放入一個Employee對象
ref="employee"表示注入的對象爲spring容器中id爲employee的對象,這樣配置後建立Company
對象後,會自動調用setEmployee()方法放入一個Employee對象
-->
<bean id="company" class="cn.springstudy.vo.Company">
<property name="employee" ref="employee"></property>
</bean>
</beans>複製代碼
接下來咱們建立一個main函數做爲程序的入口,在main函數中去建立Spring容器
package cn.springstudy.spring;
import cn.springstudy.vo.Company;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringStudy {
public static void main(String arg[]){
//方式一,XML文件中加載上下文,即Spring容器
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//從容器中獲取一個Company對象
Company company = (Company) classPathXmlApplicationContext.getBean("company");
company.supportService();
}
}複製代碼
執行一下,控制檯打印以下
咱們能夠看到咱們執行company.supportService()竟然沒報空指針,要知道咱們可沒在Company類中去建立Empoyee對象,說明什麼???Spring容器自動幫咱們建立Employee對象並set到Company對象中了。
建立一個配置Java類
package cn.springstudy.spring;
import cn.springstudy.vo.Company;
import cn.springstudy.vo.Employee;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//註解,代表這個是一個Spring配置類
@Configuration
public class SpringConfig {
//Spring容器管理的類,經過Bean註解,方法名即默認爲bean的id,也可在Bean註解後加參數指定Bean的ID
@Bean
public Employee employee(){
return new Employee();
}
//Spring容器管理的類,經過Bean註解
@Bean
public Company company(){
Company company = new Company();
company.setEmployee(employee());
return company;
}
}
複製代碼
main函數,程序入口,執行結果同上
package cn.springstudy.spring;
import cn.springstudy.vo.Company;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringStudy {
public static void main(String arg[]){
//方式二,默認bean的名稱即爲配置方法的名稱,須要用到AnnotationConfigApplicationContext容器
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
annotationConfigApplicationContext.register(SpringConfig.class);
annotationConfigApplicationContext.refresh();
Company company1 = (Company) annotationConfigApplicationContext.getBean("company");
company1.supportService();
}
}複製代碼
方式三序藉助方式一或者方式二,咱們首先須要在須要被Spring容器管理的類上面加上@Component註解,因此咱們在Empoyee加上註解
package cn.springstudy.vo;
import org.springframework.stereotype.Component;
@Component
public class Employee {
public void work(){
System.out.println("Employ start to Work");
};
}複製代碼
Company類上加上註解,需自動分配的對象上加@Autowired註解
package cn.springstudy.vo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Company {
//Autowired,幫我分配個Employee對象過來。
@Autowired
private Employee employee;
public void supportService(){
employee.work();
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
}複製代碼
在配置類上加上包自動掃描路徑
package cn.springstudy.spring;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
//cn.springstudy.vo 爲掃描的基礎包路徑
@Configuration
@ComponentScan("cn.springstudy.vo")
public class SpringConfigScan {
}複製代碼
測試main方法
package cn.springstudy.spring;
import cn.springstudy.vo.Company;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringStudy {
public static void main(String arg[]){
//方式三,需藉助方式2
AnnotationConfigApplicationContext annotationConfigApplicationContext2 = new AnnotationConfigApplicationContext();
annotationConfigApplicationContext2.register(SpringConfig.class);
annotationConfigApplicationContext2.refresh();
Company company2 = (Company) annotationConfigApplicationContext.getBean("company");
company2.supportService();
}
}複製代碼
執行結果同上。
固然XML配置方式和Java配置文件還能混着用。
一、在XML配置中混用Java配置文件只需在配置文件中增長一個<bean></bea>便可將Java配置類導入XML配置中。二、XML中導入其餘XML配置,只需用<import>指定其餘XML配置文件路徑
<?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">
<!--導入其餘XML配置文件 -->
<import resource="applicationContext2.xml"></import>
<!--Spring Java配置類-->
<bean class="cn.springstudy.spring.SpringConfig"></bean>
<bean id="employee" class="cn.springstudy.vo.Employee"></bean>
<bean id="company" class="cn.springstudy.vo.Company">
<property name="employee" ref="employee"></property>
</bean>
</beans>複製代碼
一、Java配置文件混着XML配置文件,只需在Java類中加個註解便可,二、Java配置類導入其餘配置類,只需加@Import註解,指定配置類位置。
package cn.springstudy.spring;
import cn.springstudy.vo.Company;
import cn.springstudy.vo.Employee;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
@Configuration
//導入其餘XML配置文件
@ImportResource("classpath:applicationContext.xml")
//導入其餘配置類
@Import({SpringConfigScan.class})
public class SpringConfig {
@Bean
public Employee employee(){
return new Employee();
}
@Bean
public Company company(){
Company company = new Company();
company.setEmployee(employee());
return company;
}
}複製代碼
Spring DI初步使用方法已經如上,接下來咱們主要經過XML配置的方式來講明其餘功能。
以上的小例子中Company中的Employee對象是經過setEmployee方法配置進去的。咱們還能夠經過構造方法的形式配置進去。
給Company類增長一個構造方法
package cn.springstudy.vo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
public class Company {
private Employee employee;
private String name;
public Company(Employee employee,String name){
this.employee = employee;
this.name = name;
}
public void supportService(){
employee.work();
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
}複製代碼
配置文件配置以下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/c http://www.springframework.org/schema/c/spring-c.xsd">
<!--在上面beans中聲明spring中c命名空間-->
<bean id="employee" class="cn.springstudy.vo.Employee"></bean>
<!-- 構造方法中注入Employee對象,還有一個名稱其中
c:爲命名空間前綴
emplayee、name分別爲構造函數中參數的名稱
-ref表示注入的是spring容器中的對象
"emplayee"表示引入的是id爲emplayee的對象,name沒有帶-ref則是注入字符串juejin.com
-->
<bean id="company" class="cn.springstudy.vo.Company"
c:employee-ref="employee"
c:name="juejin.com">
</bean>
</beans>複製代碼
以上說明Spring的依賴注入的基本使用。咱們在編程時候可能不是經過new來建立對象,有時也會使用靜態方法(靜態工廠模式)來建立對象,那麼Spring是否支持呢?答案是確定的。
public class ClientService {
private ClientService() {}
public static ClientService createInstance() {
return new ClientService()
}
}複製代碼
<bean id="clientService"
class="examples.ClientService"
factory-method="createInstance"/>複製代碼
固然工廠方法模式是經過非經過靜態方法建立對象的,Spring也是支持的,以下
public class DefaultServiceLocator {
private static ClientService clientService = new ClientServiceImpl();
public ClientService createClientServiceInstance() {
return clientService;
}
}複製代碼
<!-- 工廠類 -->
<bean id="serviceLocator" class="examples.DefaultServiceLocator">
</bean>
<!-- ClientService類配置 -->
<bean id="clientService"
factory-bean="serviceLocator"
factory-method="createClientServiceInstance"/>複製代碼
默認狀況下,Spring容器中的bean都是單例的,能夠經過配置修改。spring定義了多種做用域:
一、Singleton(默認) 單例
二、Prototype 原型,每次經過容器獲取對象都會建立一個新對象、
三、Session 會話,一個web會話中使用一個對象
四、Request ,每次web請求使用一個對象
經過XML配置可在bean中指定scrop屬性指定,
Java配置類可在方法上加註解@Scope("prototype")
自動掃描的類可在類上加註解@Scope("prototype")
<!-- scope 屬性指定做用域 -->
<bean id="employee" class="cn.springstudy.vo.Employee" scope="prototype"></bean>複製代碼
@Component
@Scope("prototype")
public class Company {.....}複製代碼
@Configuration
public class SpringConfig {
@Bean
@Scope("prototype")
public Employee employee(){
return new Employee();
}
}複製代碼
最後,感受這篇寫得有點亂,也很基礎,還有不少東西沒說到,不知道看到這裏的人兒有無收穫,說好的一週一篇,額,那就先發出來吧,之後可能還作修改,待續。。