Spring第一天

第一個(gè)Spring程序

1、創(chuàng)建項(xiàng)目
2、導(dǎo)入jar包spring.jarcommons-logging.jar
3、創(chuàng)建一個(gè)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
            一個(gè)bean代表一個(gè)類
          所以beans就是很多個(gè)類
     -->
     <!-- 
        一個(gè)類
        id  標(biāo)示符   
        class 類的全名
      -->
    <bean id="hello" class="spring.com.bxp.bean.Hello">
    </bean>
</beans>

5、創(chuàng)建測(cè)試類

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

IOC

概念:把對(duì)象的創(chuàng)建,初始化,銷毀交給Spring容器來(lái)做。

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

1、構(gòu)造函數(shù)
spring內(nèi)部默認(rèn)調(diào)用spring的構(gòu)造函數(shù)創(chuàng)建對(duì)象
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
            一個(gè)bean代表一個(gè)類
          所以beans就是很多個(gè)類
     -->
     <!-- 
        一個(gè)類
        id  標(biāo)示符   
        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)測(cè)試

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

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

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

(2)配置實(shí)例工廠

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

(3)測(cè)試

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標(biāo)簽

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

對(duì)象的創(chuàng)建時(shí)機(jī)

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

1、加加載配置文件

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

2、根據(jù)配置文件中的配置的bean創(chuàng)建對(duì)象,配置多少個(gè)bean,創(chuàng)建多少個(gè)對(duì)象。

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

3、獲取對(duì)象

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、獲取對(duì)象

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

如果把lazy-init值改為true,在spring啟動(dòng)的時(shí)候,檢測(cè)不到任何問(wèn)題,會(huì)存在任何問(wèn)題。所以一般情況下lazy-init的值為false。
如果一個(gè)bean中包含大量的數(shù)據(jù),不希望bean過(guò)早的停留在內(nèi)存中,此時(shí)將lazy-init的值改為true

對(duì)象的scope

在默認(rèn)情況下(scope為singleton)
在spring中創(chuàng)建的對(duì)象的單例的。將來(lái)service和dao層所有的類將放到spring中,這兩層中類的實(shí)例都是單例的,不能將屬性聲明在屬性中,會(huì)出現(xiàn)線程安全問(wèn)題。
scope為prototype:

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

lazy-init和prototype的結(jié)合

scope為prorotype,lazy-init為true
時(shí):在context.getBean()時(shí)候創(chuàng)建對(duì)象
scope為prorotype,lazy-init為false時(shí):在context.getBean()時(shí)候創(chuàng)建對(duì)象,lazy-init為false失效。
scope為prorotype,始終在context.getBean()時(shí)候創(chuàng)建對(duì)象

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

1、創(chuàng)建對(duì)象

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("構(gòu)造方法 ");
    }
    
}

2、在配置文件中進(jìn)行配置

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

1、調(diào)用構(gòu)造函數(shù)創(chuàng)建對(duì)象
2、有spring內(nèi)部調(diào)用init()方法進(jìn)行對(duì)象的初始化
3、執(zhí)行對(duì)象的方法
4、由執(zhí)行context.coose()方法時(shí)候,由spring內(nèi)部調(diào)用destory()方法

說(shuō)明

1、init()方法由spring內(nèi)部調(diào)用
2、只有在spring容器關(guān)閉的時(shí)候才會(huì)執(zhí)行,一般情況下spring容器是不會(huì)關(guān)閉的,只有在web容器銷毀的時(shí)候才關(guān)閉。
3、如果bean的配置為scope="prototype",則spring容器不負(fù)責(zé)銷毀。

IOC執(zhí)行流程

IOC執(zhí)行流程

DI(依賴注入)

給屬性賦值
1、創(chuàng)建的對(duì)象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、在配置文件對(duì)屬性進(jìn)行配置

<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容器實(shí)例化persion和hello兩個(gè)bean對(duì)象
2、利用java的反射機(jī)制調(diào)用setter方法對(duì)屬性進(jìn)行賦值。
3、調(diào)用context.getBean()獲取對(duì)象。
如果配置了init()方法,則先執(zhí)行setter方法,在執(zhí)行init方法
persion對(duì)象依賴于hello對(duì)象,如果在hello的bean標(biāo)簽上面加上lazy-init = true的屬性將會(huì)失效,因?yàn)閯?chuàng)建persion對(duì)象必須創(chuàng)建hello對(duì)象。

使用構(gòu)造器進(jìn)行賦值

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的意義:

實(shí)現(xiàn)了完全面向接口編程,客戶端沒(méi)有必要考慮具體的實(shí)現(xiàn)類是什么。

注解

概念

1、用來(lái)解釋說(shuō)明
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注解可以標(biāo)注在類上
/**
 * RetentionPolicy.SOURCE 只能在源代碼上使用
 *RetentionPolicy.CLASS 可以在源代碼上和字節(jié)碼上進(jìn)行使用
 *RetentionPolicy.RUNTIME 可以使用在源代碼,字節(jié)碼,jvm中
 */
@Retention(RetentionPolicy.RUNTIME)
@Documented  //該注解能夠出現(xiàn)在幫助文檔中
public @interface ClassInfo {
    String name() default "";//給該注解聲明一個(gè)屬性name,默認(rèn)值為""
}

方法注解

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

測(cè)試類

@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)建兩個(gè)實(shí)體類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、在配置文件中進(jìn)行配置

<?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>
   <!-- 
        啟動(dòng)依賴注入的注解解析器
     -->
    <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、測(cè)試

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

1、啟動(dòng)spring容器
2、spring容器內(nèi)部創(chuàng)建兩個(gè)對(duì)象(Persion和Student)
3、當(dāng)spring容器解析到<context:annotation-config></context:annotation-config>時(shí)啟動(dòng)依賴注入解析器
4、spring容器在容器中查找所有的bean(Persion,Student)
5、查看meigebean的每個(gè)屬性上是否有Resource注解
6、如果屬性上面有該注解,則檢查是否有name屬性
7、如果沒(méi)有name屬性,則獲取標(biāo)注的屬性的名稱,然后將該名稱和sping容器中的id進(jìn)行匹配,如果匹配成功,則進(jìn)行賦值。如果匹配不成功,則按照類型進(jìn)行匹配,如果匹配成功則賦值,如果不成功,則報(bào)錯(cuò)。
8、如果有name屬性,則把name屬性的值解析出來(lái),和spring容器中的id進(jìn)行匹配,如果匹配成功,則賦值,如果不成功則報(bào)錯(cuò)。
綜上所述:xml的效率高于注解,但是注解書寫方便。

spring中定義的注解

1、按照類型進(jìn)行匹配

@Autowired    //按照類型進(jìn)行匹配

2、按照id進(jìn)行匹配

@Autowired    
@Qualifier("student")

注解只能應(yīng)用與引用類型。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容