本文內容
- 簡單回顧IoC和DI概念
- Spring容器的概念
- 的xml配置和初始化
- 容器的基本使用
- bean的定義和初始化配置
簡單理解IoC和DI概念
什么是IoC控制反轉?
通俗地但不嚴謹地講,以前傳統方式都是應用程式需要一個物件,直接通過new的方式來生成,該物件的管理也是由當前程式自己控制,現在有一個容器,負責將應用程式需要的所有物件都new好了,物件都統一由這個容器管理,應用程式需要物件的時候直接找容器要,應用程式說我不關系物件是怎么來的反正你給我就行,這樣和以前的方式不一樣了,以前是應用程式自己創建和管理,現在交給容器統一創建管理了,控制權發生反轉了,這簡單理解為IoC,
什么是DI依賴注入?
通俗地但不嚴謹地講,應用程式需要的物件A依賴于B,由容器直接自動將B依賴給到物件A,可以理解為自動將依賴B注入到A 中了,
Spring官方的對于這個2個概念的說明,比較繞,這里也附上,
IoC is also known as dependency injection (DI). It is a process whereby objects define their dependencies (that is, the other objects they work with) only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse (hence the name, Inversion of Control) of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes or a mechanism such as the Service Locator pattern.
IoC也稱為依賴項注入(DI),在這個程序中,物件只能通過建構式引數、工廠方法的引數或在物件實體被構造或從工廠方法回傳后在物件實體上設定的屬性來定義它們的依賴關系(即它們所處理的其他物件),容器然后在創建bean時注入這些依賴項,這個程序本質上是bean本身的逆程序(因此得名“控制反轉”),它通過直接構造類來控制依賴項的實體化或位置
Spring容器的概念和使用
Spring IoC容器負責實體化、配置和組裝bean,容器通過讀取配置元資料來獲取關于實體化、配置和組裝哪些物件的指令,配置元資料以XML、Java注釋或Java代碼表示,
Talk is cheap. Show me the code
屁話少說,放碼過來
下面將通過一個案例來快速演示Spring容器的簡單使用,
環境準備
IDE: IDEA
Maven: 3.5.6
JDK: java8
創建Maven工程并Spring引入依賴
pom檔案如下
<?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>org.example</groupId>
<artifactId>spring-ioc-quickstart</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<spring.verison>5.2.19.RELEASE</spring.verison>
</properties>
<dependencies>
<!--Spring背景關系的依賴-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.verison}</version>
</dependency>
</dependencies>
<build>
<!--組態檔相關-->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.yml</include>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.yml</include>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
創建2個簡單類A、B
A依賴B如下
public class A {
private B b;
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
}
B如下
public class B {
}
創建Spring的XML組態檔
在resources目錄創建spring.xml組態檔,并配置bean
<?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">
<!--A的定義資訊-->
<bean id="a" >
<!--注入B物件依賴-->
<property name="b" ref="b"/>
</bean>
<!--B的定義資訊-->
<bean id="b" ></bean>
</beans>
創建一個測驗類
public class MainTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
A a = context.getBean("a", A.class);
B b = context.getBean("b", B.class);
System.out.println("A物件:" + a);
System.out.println("A物件中的B依賴: " + a.getB() );
System.out.println("B物件:" + b);
}
}
最終檔案目錄結構

運行結果
物件AB都統一由ClassPathXmlApplicationContext容器管理,并在A需要B依賴的時候容器自動注入,應用程式需要的時候直接從容器拿介面如context.getBean(),,結合著里面下IoC和DI的概念,以上就是Spring容器的簡單使用,
A物件:com.crab.spring.A@2d928643
A物件中的B依賴: com.crab.spring.B@5025a98f
B物件:com.crab.spring.B@5025a98f
Spring 容器物件
BeanFactory 介面
BeanFactory 介面提供了一種高級配置機制,能夠管理任何型別的物件,是Spring IoC容器根介面,主要的定義方法如下,
package org.springframework.beans.factory;
public interface BeanFactory {
// 指定名稱獲取bean
Object getBean(String name) throws BeansException;
// 指定名稱和型別獲取bean
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
// 指定型別獲取bean
<T> T getBean(Class<T> requiredType) throws BeansException;
// 容器中是否存在bean
boolean containsBean(String name);
// 是否是單例
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
//
}
非常建議閱讀
BeanFactory的原始碼上的注釋說明,非常的詳盡,常見的面試:請描述下Spring的生命周期?注釋上就有非常官方的完整說明
ApplicationContext介面
ApplicationContext介面是BeanFactory的子介面,在其基礎上提供更多企業級的功能,負責實體化、配置和組裝bean,支持xml組態檔、java注解、Java-based等方式進行bean的配置,常使用的實作類有: ClassPathXmlApplicationContext、FileSystemXmlApplicationContext、AnnotationConfigApplicationContext等,后面詳細講解和使用,請保持閱讀的熱情,
bean定義物件
在 Spring 中,構成應用程式并由 Spring IoC 容器管理的物件稱為 bean,這些 bean 是使用提供給容器的配置元資料創建的,如以 XML
<!--A的定義資訊-->
<bean id="a" >
<!--注入B物件依賴-->
<property name="b" ref="b"/>
</bean>
xml中<bean />配置格式和支持元素如下:
<bean id="myChild"
init-method="init"
destroy-method="destroy"
name="childBean,aliasName"
parent="myParent"
scope="singleton"
primary="true"
depends-on="myParent"
autowire="byType"
autowire-candidate="true"
factory-bean="myFactory"
factory-method="getObj"
abstract="false"
></bean>
| 元素 | 說明 |
|---|---|
| id | 唯一ID |
| class | 對應的類,全路徑 |
| name | 支持名稱,可以逗號/分號/空格來分隔多個,多個名稱可用作別名 |
| init-method | 自定義的初始化方法 |
| destroy-method | 自定義的bean被銷毀的方法 |
| parent | 指定父類參考 |
| scope | 指定作用域,如單例和原型,后面詳細講 |
| primary | 是否是主要的,用于依賴注入時候容器內有多個同型別的bean時做選擇 |
| depends-on | 依賴于容器中的另外一個bean的參考 |
| autowire | 自動注入依賴,指定通過名稱或是型別 |
| autowire-candidate | 標記自動依賴注入時候選 |
| factory-bean | 指定創建該bean的工廠 |
| factory-method | 指定創建的工廠方法 |
| abstract | 是否是抽象 |
| lazy-init | 延遲加載 |
通常情況下,如果不顯式指定
name,Spring默認生成名稱的規則是:將類名稱轉成小駝峰式來命名bean,如AccountManager生成accountManager,
在Spring容器內,bean的定義資訊最終是通過介面BeanDefinition及其實作類體現,BeanDefinition介面和抽象類AbstractBeanDefinition`,主要定義如下
package org.springframework.beans.factory.config;
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
void setParentName(@Nullable String parentName);
void setBeanClassName(@Nullable String beanClassName);
void setScope(@Nullable String scope);
void setLazyInit(boolean lazyInit);
void setDependsOn(@Nullable String... dependsOn);
void setAutowireCandidate(boolean autowireCandidate);
void setPrimary(boolean primary);
void setFactoryBeanName(@Nullable String factoryBeanName);
void setFactoryMethodName(@Nullable String factoryMethodName);
void setInitMethodName(@Nullable String initMethodName);
void setDestroyMethodName(@Nullable String destroyMethodName);
// 省略
}
package org.springframework.beans.factory.support;
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
implements BeanDefinition, Cloneable {
private volatile Object beanClass;
private String scope = SCOPE_DEFAULT;
private boolean abstractFlag = false;
private Boolean lazyInit;
private int autowireMode = AUTOWIRE_NO;
private String[] dependsOn;
private boolean autowireCandidate = true;
private boolean primary = false;
private String factoryBeanName;
private String factoryMethodName;
private String initMethodName;
private String destroyMethodName;
}
總結
本文主要講解了Ioc的概念,演示Spring Ioc容器的快速使用,并詳細說明bean定義元素,下一篇將講bean的依賴注入,
本文對應的原始碼:
https://github.com/kongxubihai/pdf-spring-series/tree/main/spring-ioc-quickstart
知識分享,轉載請注明出處,學無先后,達者為先!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/412856.html
標籤:Java
上一篇:java學習筆記day1
