1. 程式人生 > >spring框架核心思想以及注入方式(一)

spring框架核心思想以及注入方式(一)

1.spring用來整合其它框架和技術
2. 將事務的控制放在配置檔案中管理(宣告式事務),用來取代程式設計式事務
3. spring的核心思想

   IOC(Inversion of Controller)控制反轉 
   將管理java類的控制權交給了spring容器
   控制反轉是所有的容器都具有的特性,不能很好區分spring與其他容器的不同,因此後來又提出了依賴注入的概念
   DI(Ddpendency Inject)依賴注入
   不僅要由spring容器來管理java類的建立,而且要管理類與類之間的依賴關係  
   AOP(Aspect):面向切面程式設計

4.spring(微容器):管理 Dao,Service,Hibert,Action等等的生命週期,對這些java類的建立,使用,銷燬進行管理(實體類是由hibernate管理)
5. 對java類進行管理 (示例程式碼)

 <?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:context="http://www.springframework.org/schema/context"  
    xmlns:tx="http://www.springframework.org/schema/tx"   
    xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
> <!-- bean標籤用來管理java類 id是唯一標識 calss 是要例項化的類名稱(全名) 需要有一個預設的構造方法 --> <bean id="empDao" class="com.lmr.dao.EmpDaoImpl"> </bean> <bean id="empService" class="com.lmr.service.EmpServiceImpl" init-method="init" destroy-method="destory"> <!-- 當spring初始化service的時候回根據property的配置為 empService屬性賦值 service引導dao層方法 name 是引用的屬性名 ref是引用的bean的id --> <property name="empDao" ref="empDao"></property> </bean> </beans> public class EmpServiceImpl implements EmpService{ //定義一個dao層介面的成員變數,並新增set方法 private EmpDao empDao; public void save(Object obj){ System.out.println("service 的save方法"); empDao.save(obj); } public void init(){ System.out.println("初始化方法"); } public void destory(){ System.out.println("銷燬方法"); } public EmpDao getEmpDao() { return empDao; } public void setEmpDao(EmpDao empDao) { this.empDao = empDao; } public class EmpDaoImpl implements EmpDao{ public void save(Object obj) { System.out.println("dao 層 save"); } } public class Test2 { public static void main(String[] args) { //使用spring容器獲得物件 建立spring容器 ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml"); //根據配置類的唯一標識(id)獲取它的例項 EmpDao empDao =(EmpDao) ac.getBean("empDao"); EmpDao empDao2 =(EmpDao) ac.getBean("empDao"); System.out.println(empDao==empDao2); empDao.save(new Object()); EmpService empService = (EmpService)ac.getBean("empService"); empService.save(new Object()); } }

6.通過spring,可以通過配置檔案更換實現,而不用修改java程式碼

    ①:實現類實現介面,當實現類變成另一個實現類的時候不用去修改java程式碼,而new出來的實現類需要去修改程式碼
    ②:spring簡化程式碼實現類只建立一個例項(預設情況下,一個spring只會建立實現類的一個例項  單例),而在程式碼中new 實現類 會出現多個例項,多佔用記憶體,且後期不容易維護
    ③:通過依賴注入的方式,建立類與類之間的關係
    <property name="要注入的屬性的名稱" ref="要注入的類的id"> 要注入的屬性必須實現響應的set方法

7.bean 中的作用域屬性 scope

singleton:單例模式
prototype:多例模式

8.bean中的初始化方法和銷燬方法的配置

init-method="init"  init初始化方法的名稱
destory-method="destory"  destory銷燬方法的名稱
ClassPathXmlApplicationContext 中才有正常關閉spring容器的close()方法,測試銷燬方法需要建立此物件

二:spring的四種注入方式

  • set方法注入
public class App1 {
    //使用傳統的方法
            /*UserService user = new UserService();
            user.setName("XXXX");
            user.sayHello();*/


            //使用spring
            //1.得到spring的applicationContext物件(容器物件)
            //當ClassPathXmlApplication("applicationContext.xml")執行的時候,我們的spring容器物件被建立
            //同時applicationContext.xml中配置bean就會被建立(記憶體)

    /**
     * 這是使用ClassPathXmlApplicationContext()建立bean
     */
    @Test
    public void testClassPathXmlApplicationContext(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("com/hsp/service1/beans.xml");
        UserService userService = ac.getBean("userService", UserService.class);
        System.out.println(userService.getName()+"=========="+userService.getByService().getName());
    }

    /**
     * 這是使用XmlBeanFactory()建立bean
     */
    @Test
    public void testXmlBeanFactory(){
        BeanFactory factory = new XmlBeanFactory(new ClassPathResource("com/hsp/service1/beans.xml"));
        UserService userService = factory.getBean("userService", UserService.class);        
        System.out.println(userService.getName()+"************"+userService.getByService().getName());
    }


}


public class ByService {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void sayByService() {
        System.out.println("呼叫ByService的sayByService方法:"+name);
    }


public class UserService {
    private String name;
    private ByService byService;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public ByService getByService() {
        return byService;
    }
    public void setByService(ByService byService) {
        this.byService = byService;
    }
    public void sayUserService() {
        System.out.println("呼叫UserService的sayUserService方法:"+name);
    }


<!-- 在容器檔案中配置bean(service/dao/domain/action/資料來源) -->
<!--bean元素的作用是,當我們的spring框架載入的時候,spring就會自動的建立一個bean 放入記憶體中去  
    UserService userservice = new UserService() 
    userService.setName("劉明然"); 
-->
<bean id="userService" class="com.hsp.service1.UserService">
    <!-- 這裡體現注入的概念 -->
    <property name="name">
        <value>XXX</value>
    </property>
    <!-- 在userService中引入byService -->
    <property name="byService" ref="byService"/>
</bean>

<bean id="byService" class="com.hsp.service1.ByService">
    <property name="name" value="XXX1"></property>
</bean>
  • 構造方法注入
public class EmpServiceImpl implements EmpService{
    //定義一個dao層介面的成員變數,並新增set方法
    private EmpDao empDao;

    public EmpServiceImpl(EmpDao empDao){
        this.empDao = empDao;
    }

    public void save(Object obj){
        System.out.println("service 的save方法");
        empDao.save(obj);
    }


    public void init(){
        System.out.println("初始化方法");
    }

    public void destory(){
        System.out.println("銷燬方法");
    }

    /*public EmpDao getEmpDao() {
        return empDao;
    }
    public void setEmpDao(EmpDao empDao) {
        this.empDao = empDao;
    }*/


}

<!-- 
    利用構造方法注入 
    index 引數下表 從0開始  ref 引用id
    多個引數的時候寫多個<constructor-arg>
-->
    <constructor-arg index="0" ref="empDao"/>
  • 直接給屬性注入,需要使用註解
  • 自動織入(本質上仍然使用了set的方法注入) Autowired
    byName 根據屬性名與引用的id進行匹配,名稱一致則注入
    byType根據型別進行匹配,當同一個介面有2個實現類的時候就會報錯,不知道使用哪個實現類