Spring第一天

第一個Spring程序

1、創(chuàng)建項目
2涮较、導入jar包spring.jarcommons-logging.jar
3稠鼻、創(chuàng)建一個javabean類

public class Hello {
    public void hello(){
        System.out.println("hello");
    }
}

4、在src目錄下創(chuàng)建applicationContext.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-2.5.xsd">
    <!-- 
        beans
            一個bean代表一個類
          所以beans就是很多個類
     -->
     <!-- 
        一個類
        id  標示符   
        class 類的全名
      -->
    <bean id="hello" class="spring.com.bxp.bean.Hello">
    </bean>
</beans>

5狂票、創(chuàng)建測試類

public class Test {
    public static void main(String[] args) {
//啟動spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//從spring容器中提取bean
        Hello hello = (Hello) context.getBean("hello");
        hello.hello();
    }
}

IOC

概念:把對象的創(chuàng)建候齿,初始化,銷毀交給Spring容器來做闺属。

Spring創(chuàng)建對象的方式

1慌盯、構造函數
spring內部默認調用spring的構造函數創(chuàng)建對象
2、靜態(tài)工廠
(1)創(chuàng)建靜態(tài)工廠

public class HelloFactory {
    public  static Hello getInstance(){
        return new Hello();
    }
}

(2)配置工廠

<?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-2.5.xsd">
    <!-- 
        beans
            一個bean代表一個類
          所以beans就是很多個類
     -->
     <!-- 
        一個類
        id  標示符   
        class 類的全名
      -->
    <bean id="hello" class="spring.com.bxp.bean.Hello">
    </bean>
    <!-- 配置靜態(tài)工廠 -->
    <bean id="hello2" class="spring.com.bxp.bean.HelloFactory" factory-method="getInstance"></bean>
</beans>

(3)測試

public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Hello hello = (Hello) context.getBean("hello2");
        hello.hello();
    }
}

3掂器、實例工廠
(1)創(chuàng)建實例工廠(使用最多)

public class HelloFactory {
    public  Hello getInstance(){
        return new Hello();
    }
}

(2)配置實例工廠

<?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-2.5.xsd">
    <!-- 
        beans
            一個bean代表一個類
          所以beans就是很多個類
     -->
     <!-- 
        一個類
        id  標示符   
        class 類的全名
      -->
    <bean id="hello" class="spring.com.bxp.bean.Hello">
    </bean>
  
    <!-- 配置實例工廠 -->
    <bean id="helloFactory" class="spring.com.bxp.bean.HelloFactory"></bean>
    <!--  factory-bean對象工廠  factory-method對象工廠方法 -->
    <bean id="hello3" factory-bean="helloFactory" factory-method="getInstance"></bean>
</beans>

(3)測試

public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Hello hello = (Hello) context.getBean("hello3");
        hello.hello();
    }
}

使用別名

在applicationContext.xml文件中使用alias標簽

  <bean id="hello" class="spring.com.bxp.bean.Hello">
    </bean>
    <alias name="hello" alias="he"/>

對象的創(chuàng)建時機

默認創(chuàng)建方式
<bean id="hello" class="spring.com.bxp.bean.Hello">

1亚皂、加加載配置文件

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

2、根據配置文件中的配置的bean創(chuàng)建對象国瓮,配置多少個bean灭必,創(chuàng)建多少個對象。

public Hello() {
        // TODO Auto-generated constructor stub
        System.out.println("構造方法 ");
    }

3乃摹、獲取對象

Hello hello = (Hello) context.getBean("hello3");
延遲創(chuàng)建(配置lazy-init屬性)
 <bean id="hello" lazy-init="true" class="spring.com.bxp.bean.Hello">

1禁漓、加加載配置文件

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

2、獲取對象

Hello hello = (Hello) context.getBean("hello3");
//獲取對象的同時創(chuàng)建對象
public Hello() {
        // TODO Auto-generated constructor stub
        System.out.println("構造方法 ");
    }
意義

如果把lazy-init值改為true孵睬,在spring啟動的時候播歼,檢測不到任何問題,會存在任何問題肪康。所以一般情況下lazy-init的值為false荚恶。
如果一個bean中包含大量的數據撩穿,不希望bean過早的停留在內存中磷支,此時將lazy-init的值改為true

對象的scope

在默認情況下(scope為singleton)
在spring中創(chuàng)建的對象的單例的。將來service和dao層所有的類將放到spring中食寡,這兩層中類的實例都是單例的雾狈,不能將屬性聲明在屬性中,會出現線程安全問題抵皱。
scope為prototype:

<bean scope="prototype" id="hello" lazy-init="false" class="spring.com.bxp.bean.Hello">

lazy-init和prototype的結合

scope為prorotype善榛,lazy-init為true
時:在context.getBean()時候創(chuàng)建對象
scope為prorotype辩蛋,lazy-init為false時:在context.getBean()時候創(chuàng)建對象,lazy-init為false失效移盆。
scope為prorotype悼院,始終在context.getBean()時候創(chuàng)建對象

對象的創(chuàng)建和銷毀

1、創(chuàng)建對象

public class Hello {
    
    public void init(){
        System.out.println("初始化方法");
    }
    public void destorym(){
        System.out.println("銷毀方法");
    }
    public void hello(){
        System.out.println("hello");
    }
    public Hello() {
        // TODO Auto-generated constructor stub
        System.out.println("構造方法 ");
    }
    
}

2咒循、在配置文件中進行配置

<bean id="hello"  class="spring.com.bxp.bean.Hello"
    lazy-init="false"  init-method="init" 
    destroy-method="destorym">
執(zhí)行順序

1据途、調用構造函數創(chuàng)建對象
2、有spring內部調用init()方法進行對象的初始化
3叙甸、執(zhí)行對象的方法
4颖医、由執(zhí)行context.coose()方法時候,由spring內部調用destory()方法

說明

1裆蒸、init()方法由spring內部調用
2熔萧、只有在spring容器關閉的時候才會執(zhí)行,一般情況下spring容器是不會關閉的僚祷,只有在web容器銷毀的時候才關閉佛致。
3、如果bean的配置為scope="prototype"久妆,則spring容器不負責銷毀晌杰。

IOC執(zhí)行流程

IOC執(zhí)行流程

DI(依賴注入)

給屬性賦值
1、創(chuàng)建的對象Persion

public class Persion {
    private long id;
    private String name;
    private List list;
    private Set set;
    private Map map;
    private Properties pro;
    private Hello hello;
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List getList() {
        return list;
    }
    public void setList(List list) {
        this.list = list;
    }
    public Set getSet() {
        return set;
    }
    public void setSet(Set set) {
        this.set = set;
    }
    public Map getMap() {
        return map;
    }
    public void setMap(Map map) {
        this.map = map;
    }
    public Properties getPro() {
        return pro;
    }
    public void setPro(Properties pro) {
        this.pro = pro;
    }
    public Hello getHello() {
        return hello;
    }
    public void setHello(Hello hello) {
        this.hello = hello;
    }
}

2筷弦、在配置文件對屬性進行配置

<bean id="persion" class="spring.com.bxp.bean.Persion">
      <!-- name:屬性, value:值肋演, 引用類型使用ref賦值 -->
        <property name="id" value="3"></property>
        <property name="name" value="張三"></property>
        
        <property name="hello" ref="hello"></property>
        
        <property name="list">
            <list>
                <value>list1</value>
                <value>list2</value>
                <ref bean="hello"/>
            </list>
        </property>
        
        <property name="set">
            <set>
                <value>set1</value>
                <value>set2</value>
                <ref bean="hello"/>
            </set>
        </property>
        
        <property name="pro">
            <props>
                <prop key="pro1">pro1</prop>
                <prop key="pro2">pro2</prop>
            </props>
        </property>
        
        <property name="map">
            <map>
                <entry key="entry1">
                    <value>entry1</value>
                </entry>
                <entry key="entry2">
                    <ref bean="hello"/>
                </entry>
            </map>
        </property>
      </bean>
      
    <bean id="hello"  class="spring.com.bxp.bean.Hello"
    lazy-init="false" init-method="init" 
    destroy-method="destorym">
    </bean>
步驟:

1、spring容器實例化persion和hello兩個bean對象
2烂琴、利用java的反射機制調用setter方法對屬性進行賦值爹殊。
3、調用context.getBean()獲取對象奸绷。
如果配置了init()方法梗夸,則先執(zhí)行setter方法,在執(zhí)行init方法
persion對象依賴于hello對象号醉,如果在hello的bean標簽上面加上lazy-init = true的屬性將會失效反症,因為創(chuàng)建persion對象必須創(chuàng)建hello對象。

使用構造器進行賦值

public Persion(long id, String name) {
        super();
        this.id = id;
        this.name = name;
    }

在配置文件中

 <bean id="persion" class="spring.com.bxp.bean.Persion">
        <constructor-arg index="0" value="1"></constructor-arg>
        <constructor-arg index="1" type="java.lang.String" value="張三"></constructor-arg>
      </bean>

IOC和DI的意義:

實現了完全面向接口編程畔派,客戶端沒有必要考慮具體的實現類是什么铅碍。

注解

概念

1、用來解釋說明
2线椰、必須作用于類的某一部分
3胞谈、注解的作用于范圍(java,class,jvm)
4烦绳、注解解析器

自定義注解

類注解

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)//classInfo注解可以標注在類上
/**
 * RetentionPolicy.SOURCE 只能在源代碼上使用
 *RetentionPolicy.CLASS 可以在源代碼上和字節(jié)碼上進行使用
 *RetentionPolicy.RUNTIME 可以使用在源代碼卿捎,字節(jié)碼,jvm中
 */
@Retention(RetentionPolicy.RUNTIME)
@Documented  //該注解能夠出現在幫助文檔中
public @interface ClassInfo {
    String name() default "";//給該注解聲明一個屬性name径密,默認值為""
}

方法注解

@Target(ElementType.METHOD)//classInfo注解可以標注在類上
/**
 * RetentionPolicy.SOURCE 只能在源代碼上使用
 *RetentionPolicy.CLASS 可以在源代碼上和字節(jié)碼上進行使用
 *RetentionPolicy.RUNTIME 可以使用在源代碼午阵,字節(jié)碼,jvm中
 */
@Retention(RetentionPolicy.RUNTIME)
@Documented  //該注解能夠出現在幫助文檔中
public @interface MethodInfo {
    String value() default "";
}

測試類

@ClassInfo(name = "這是類")
public class MyClass {
    
    @MethodInfo("這是方法")
    public void fun(){
        
    }
}

解析注解

public void parse() {
        Class clazz = MyClass.class;

        if (clazz.isAnnotationPresent(ClassInfo.class)) {
            ClassInfo classInfo = (ClassInfo) clazz
                    .getAnnotation(ClassInfo.class);
            System.out.println(classInfo.name());
        }

        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            if (method.isAnnotationPresent(MethodInfo.class)) {
                MethodInfo methodInfo = method.getAnnotation(MethodInfo.class);
                System.out.println(methodInfo.value());
            }
        }
    }

Spring中的注解

案例:

1享扔、創(chuàng)建兩個實體類Persion和Student

public class Persion {
    
    @Resource(name = "student")
    private Student student;
    public void say(){
        student.say();
    }
}


public class Student {
    public void say(){
        System.out.println("student");
    }
}

2趟庄、在配置文件中進行配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       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-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">
    
   <bean id="persion" class="spring.com.bxp.bean.Persion"></bean>
   <bean id="student" class="spring.com.bxp.bean.Student"></bean>
   <!-- 
        啟動依賴注入的注解解析器
     -->
    <context:annotation-config></context:annotation-config>
</beans>

引入依賴注入的注解解析器需要的名稱空間

xmlns:context="http://www.springframework.org/schema/context"

  http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context-2.5.xsd"

3、測試

public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Persion persion = (Persion) context.getBean("persion");
        persion.say();
    }  
注解依賴注入的步驟:

1伪很、啟動spring容器
2戚啥、spring容器內部創(chuàng)建兩個對象(Persion和Student)
3、當spring容器解析到<context:annotation-config></context:annotation-config>時啟動依賴注入解析器
4锉试、spring容器在容器中查找所有的bean(Persion猫十,Student)
5、查看meigebean的每個屬性上是否有Resource注解
6呆盖、如果屬性上面有該注解拖云,則檢查是否有name屬性
7、如果沒有name屬性应又,則獲取標注的屬性的名稱宙项,然后將該名稱和sping容器中的id進行匹配,如果匹配成功株扛,則進行賦值尤筐。如果匹配不成功,則按照類型進行匹配洞就,如果匹配成功則賦值盆繁,如果不成功,則報錯旬蟋。
8油昂、如果有name屬性,則把name屬性的值解析出來倾贰,和spring容器中的id進行匹配冕碟,如果匹配成功,則賦值匆浙,如果不成功則報錯安寺。
綜上所述:xml的效率高于注解,但是注解書寫方便吞彤。

spring中定義的注解

1我衬、按照類型進行匹配

@Autowired    //按照類型進行匹配

2、按照id進行匹配

@Autowired    
@Qualifier("student")

注解只能應用與引用類型饰恕。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末挠羔,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子埋嵌,更是在濱河造成了極大的恐慌破加,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件雹嗦,死亡現場離奇詭異范舀,居然都是意外死亡,警方通過查閱死者的電腦和手機了罪,發(fā)現死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門锭环,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人泊藕,你說我怎么就攤上這事辅辩。” “怎么了娃圆?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵玫锋,是天一觀的道長。 經常有香客問我讼呢,道長撩鹿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任悦屏,我火速辦了婚禮节沦,結果婚禮上,老公的妹妹穿的比我還像新娘础爬。我一直安慰自己散劫,他們只是感情好,可當我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布幕帆。 她就那樣靜靜地躺著获搏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪失乾。 梳的紋絲不亂的頭發(fā)上常熙,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天,我揣著相機與錄音碱茁,去河邊找鬼裸卫。 笑死,一個胖子當著我的面吹牛纽竣,可吹牛的內容都是我干的墓贿。 我是一名探鬼主播茧泪,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼聋袋!你這毒婦竟也來了队伟?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤幽勒,失蹤者是張志新(化名)和其女友劉穎嗜侮,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體啥容,經...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡锈颗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了咪惠。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片击吱。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情遥皂,我是刑警寧澤鸽嫂,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜憨奸,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望凿试。 院中可真熱鬧排宰,春花似錦、人聲如沸那婉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽详炬。三九已至盐类,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間呛谜,已是汗流浹背在跳。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留隐岛,地道東北人猫妙。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像聚凹,于是被迫代替她去往敵國和親割坠。 傳聞我的和親對象是個殘疾皇子齐帚,可洞房花燭夜當晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內容