日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

java调用外联服务用xml,Spring IOC 依赖注入的两种方式:XML和注解

發布時間:2023/12/1 asp.net 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java调用外联服务用xml,Spring IOC 依赖注入的两种方式:XML和注解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

IoC,直觀地講,就是容器控制程序之間的關系,而非傳統實現中,由程序代碼直接操控。這也就是所謂“控制反轉”的概念所在。控制權由應用代碼中轉到了外部容器,控制權的轉移是所謂反轉。IoC還有另外一個名字——“依賴注入(Dependency Injection)”。從名字上理解,所謂依賴注入,即組件之間的依賴關系由容器在運行期決定,形象地說,即由容器動態地將某種依賴關系注入到組件之中。

依賴注入的原理

依賴注入的方式---XML配置

依賴注入的方式---注解的方式

Spring 它的核心就是IOC和AOP。而IOC中實現Bean注入的實現方式之一就是DI(依賴注入)。

一 DI的原理

DI的基本原理:對象之間的依賴關系只會通過三種方式:構造函數參數,工廠方法的參數以及構造函數或工廠方法創建的對象屬性設置。因此,容器的工作哦就是在創建Bean時注入所有的依賴關系。相對于由Bean自己控制其實例化,直接在構造器中指定依賴關系或者類似服務定位器(Service Locator)這三種自主控制依賴關系注入的方法,而控制權從根本上發生改變,即控制反轉(Inverse of Controll)---IOC.

應用DI規則后,我們不用在關注對象之間的依賴關系,從而達到高層次的松耦合。DI有兩種實現方式---Setter/getter方式(傳值方式)和構造器方式(引用方式)。

下面通過一個生動形象的例子介紹控制反轉。

比如,一個女孩希望找到合適的男朋友,如圖6-2所示,可以有3種方式,即青梅竹馬、親友介紹、父母包辦。

第1種方式是青梅竹馬,如圖6-3所示。

通過代碼表示如下。

public class Girl {

void kiss(){

Boy boy = new Boy();

}

}

第2種方式是親友介紹,如圖6-4所示。

通過代碼表示如下。

public class Girl {

void kiss(){

Boy boy = BoyFactory.createBoy();

}

}

第3種方式是父母包辦,如圖6-5所示。

通過代碼表示如下。

public class Girl {

void kiss(Boy boy){

// kiss boy

boy.kiss();

}

}

哪一種為控制反轉IoC呢?雖然在現實生活中我們都希望青梅竹馬,但在Spring世界里,選擇的卻是父母包辦,它就是控制反轉,而這里具有控制力的父母,就是Spring所謂的容器概念。

典型的IoC可以如圖6-6所示。

二、DI的方式---XML配置

第1種是通過接口注射,這種方式要求我們的類必須實現容器給定的一個接口,然后容器會利用這個接口給我們這個類注射它所依賴的類。Setter/getter方法

這種方式也是Spring推薦的方式

1)、beans.xml (外部注入的方式)

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

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

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.or...

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

2) PersonDao.java

package com.spring.dao;

public interface PersonDao {

public void add();

}

3) PersonDaoImpl.java

package com.spring.dao.impl;

import com.spring.dao.PersonDao;

public class PersonDaoImpl implements PersonDao {

public void add() {

System.out.println("PersonDao.add() is running.");

}

}

4) PersonService.java

package com.spring.service;

public interface PersonService {

public? void save();

}

5) PersonServiceBean.java

package com.spring.service.impl;

import com.spring.dao.*;

import com.spring.service.PersonService;

import javax.annotation.PostConstruct;

import javax.annotation.PreDestroy;

public class PersonServiceBean implements PersonService {

private PersonDao personDao;

public PersonServiceBean(){

System.out.println("personServiceBean.constructor() is running.");

}

public PersonDao getPersonDao() {

return personDao;

}

public void setPersonDao(PersonDao personDao) {

this.personDao = personDao;

}

public void save(){

System.out.println("Name:" );

personDao.add();

}

@PostConstruct

public void init(){

System.out.println("PersonServiceBean.init() is running.");

}

@PreDestroy

public void destory(){

System.out.println("PersonServiceBean.destory() is running.");

}

}

6) SpringIOCTest.java(測試類)

package junit.test;

import org.junit.BeforeClass;

import org.junit.Test;

import org.springframework.context.support.AbstractApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.spring.service.PersonService;

public class SpringIOCTest {

@BeforeClass

public static void setUpBeforeClass() throws Exception {

}

@Test public void instanceSpring(){

AbstractApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

PersonService personService = (PersonService)context.getBean("personService");

personService.save();

//????????? context.close();

}

}

我們還可以采用內部注入的方式來處理:

Beans.xml修改如下:

2、構造器注入

這種方式Spring同樣給予了實現,它和通過setter方式一樣,都在類里無任何侵入性,但是,不是沒有侵入性,只是把侵入性轉移了,顯然第1種方式要求實現特定的接口,侵入性非常強,不方便以后移植

2) PersonService.java:同Setter方法注入

3) PersonServiceBean.java

public class PersonServiceBean implements PersonService {

private PersonDao personDao;

private String name;

public PersonServiceBean(){

System.out.println("personServiceBean.constructor() is running.");

}

public PersonServiceBean(PersonDao personDao, String name) {

this.personDao = personDao;

this.name = name;

}

//????? public PersonDao getPersonDao() {

//????????? return personDao;

//????? }

//???? public void setPersonDao(PersonDao personDao) {

//???????? this.personDao = personDao;

//????? }

public void save(){

System.out.println("Name:"+name );

personDao.add();

}

@PostConstruct

public void init(){

System.out.println("PersonServiceBean.init() is running.");

}

@PreDestroy

public void destory(){

System.out.println("PersonServiceBean.destory() is running.");

}

}

4) PersonDao.java:同Setter方法注入

5) PersonDaoImpl.java:同Setter方法注入

6) 測試類(SpringIOCTest.java):同上

控制臺信息

PersonServiceBean.init() is running.

Name:Jamson

PersonDao.add() is running.

PersonServiceBean.destory() is running.

三 DI的方式---注解的配置

自從Jdk5中引入Annotation類后,在EJB和Spring中得到廣泛的使用,也越來越被開發者們在平時的應用中使用。主要是用在Field上的注入。在日常的應用開發中,一個項目中有很多的bean,如果使用XML文件配置,就會導致配置文件難以管理。使用注解注入的時候,能夠使bean的配置文件內容不至于繁雜。

1、古老的注入方式:

實現類:

Java代碼 /**

@title UserServiceImpl.java

@description UserService實現類

@author cao_xhu

@version

@create_date Oct 30, 2009

@copyright (c) CVIC SE

*/

public class UserServiceImpl implements UserService {

private UserDAO userDAO;

public void setUserDAO(UserDAO userDAO) {

this.userDAO = userDAO;

}

...

}

配置文件:

Xml代碼

class="springlive.service.impl.UserServiceImpl">

2、使用注解的方式:

2.1、Autowired注解

<1>對成員變量注解

實現類:

Java代碼 @Autowired

private IndustryDao industryDao;

...

<2>set方法注解

Java代碼 @Autowired

public void setDao(IndustryDao industryDao)

{

super.setDao(industryDao);

}

配置文件:

Xml代碼

class="efs.sadapter.system.industry.dao.hibernate.HibernateIndustryDao" />

class="efs.sadapter.system.industry.service.impl.IndustryServiceImpl" />

@Autowired可以對成員變量、方法和構造函數進行標注,來完成自動注入。

@Autowired的標注位置不同,它們都會在Spring在初始化industryService這個bean時,自動裝配industryDao這個屬性,區別是:第一種實現中,Spring會直接將IndustryDao類型的唯一一個bean賦值給industryDao這個成員變量;第二種實現中,Spring會調用setDao方法來將IndustryDao類型的唯一一個bean裝配到industryDao這個屬性。

2.2、@Qualifier

@Autowired是根據類型進行自動注入的,如果spring配置文件中存在多個IndustryDao類型的bean時,或者不存在IndustryDao類型的bean,都會拋出異常。

存在多個類型的實例時,按id注入@Qualifier("core.system.hibernateService")

Java代碼 HibernateService hibernateService;

@Autowired

public void setHibernateService(@Qualifier("core.system.hibernateService")

HibernateService hibernateService)

{

this.hibernateService = hibernateService;

}

若不存在某類型的實例:告訴 Spring:在找不到匹配 Bean 時也不報錯

Java代碼 @Autowired(required = false)

public void setHibernateService(@Qualifier("core.system.hibernateService")

HibernateService hibernateService)

{

this.hibernateService = hibernateService;

}

2.3、使用 JSR-250 的注解

<1> @Resource

spring支持@Resource、@PostConstruct以及@PreDestroyJSR-250的標準注解。

@Resource可以按type注入,也可以按name注入。@Resource默認按byName自動注入。

Spring將@Resource注解的name屬性解析為bean的名字,而type屬性則解析為bean的類型。所以如果使用name屬性,則使用byName的自動注入策略,而使用type屬性時則使用byType自動注入策略。如果既不指定name也不指定type屬性,這時將通過反射機制使用byName自動注入策略。

@Resource裝配順序

如果同時指定了name和type,則從Spring上下文中找到唯一匹配的bean進行裝配,找不到則拋出異常

如果指定了name,則從上下文中查找名稱(id)匹配的bean進行裝配,找不到則拋出異常

如果指定了type,則從上下文中找到類型匹配的唯一bean進行裝配,找不到或者找到多個,都會拋出異常

如果既沒有指定name,又沒有指定type,則自動按照byName方式進行裝配(見2);如果沒有匹配,則回退為一個原始類型(UserDao)進行匹配,如果匹配則自動裝配;

<2> @PostConstruct 和 @PreDestroy

Spring 容器中的 Bean 是有生命周期的,Spring 允許在 Bean 在初始化完成后以及 Bean 銷毀前執行特定的操作,您既可以通過實現 InitializingBean/DisposableBean 接口來定制初始化之后 / 銷毀之前的操作方法,也可以通過 元素的 init-method/destroy-method 屬性指定初始化之后 / 銷毀之前調用的操作方法。

JSR-250 為初始化之后/銷毀之前方法的指定定義了兩個注釋類,分別是 @PostConstruct 和 @PreDestroy,這兩個注釋只能應用于方法上。標注了 @PostConstruct 注釋的方法將在類實例化后調用,而標注了 @PreDestroy 的方法將在類銷毀之前調用。

使用 @PostConstruct 和 @PreDestroy 注釋的 Boss.java

Java代碼 package com.baobaotao;

import javax.annotation.Resource;

import javax.annotation.PostConstruct;

import javax.annotation.PreDestroy;

public class Boss {

@Resource

private Car car;

@Resource(name = "office")

private Office office;

@PostConstruct

public void postConstruct1(){

System.out.println("postConstruct1");

}

@PreDestroy

public void preDestroy1(){

System.out.println("preDestroy1");

}

}

測試類代碼:

Java代碼 package com.baobaotao;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AnnoIoCTest {

public static void main(String[] args) {

String[] locations = {"beans.xml"};

ClassPathXmlApplicationContext ctx =

new ClassPathXmlApplicationContext(locations);

Boss boss = (Boss) ctx.getBean("boss");

System.out.println(boss);

ctx.destroy();// 關閉 Spring 容器,以觸發 Bean 銷毀方法的執行

}

}

標注了 @PostConstruct 的 postConstruct1() 方法將在 Spring 容器啟動時,創建 Boss Bean 的時候被觸發執行,而標注了 @PreDestroy 注釋的 preDestroy1() 方法將在 Spring 容器關閉前銷毀 Boss Bean 的時候被觸發執行。

3、使用 @Component

雖然我們可以通過 @Autowired 或 @Resource 在 Bean 類中使用自動注入功能,但是 Bean 還是在 XML 文件中通過 進行定義 —— 也就是說,在 XML 配置文件中定義 Bean,通過 @Autowired 或 @Resource 為 Bean 的成員變量、方法入參或構造函數入參提供自動注入的功能。能否也通過注釋定義 Bean,從 XML 配置文件中完全移除 Bean 定義的配置呢?答案是肯定的,我們通過 Spring 2.5 提供的 @Component 注釋就可以達到這個目標了。

下面,我們完全使用注釋定義 Bean 并完成 Bean 之間裝配:

使用 @Component 注釋的Woman.java

Java代碼 @Component

public class Woman{

}

使用 @Component 注釋的Woman.java

Java代碼 @Component

public class Man{

}

這樣,我們就可以在 Human類中通過 @Autowired 注入前面定義的 Woman和 Man Bean 了。

Java代碼 @Component("human")

public class Human{

@Autowired

private Woman woman;

@Autowired

private Man man;

}

一般情況下,Bean 都是 singleton 的,需要注入 Bean 的地方僅需要通過 byType 策略就可以自動注入了,所以大可不必指定 Bean 的名稱。如果需要使用其它作用范圍的 Bean,可以通過 @Scope 注釋來達到目標:

Java代碼 @Scope("prototype")

@Component("human")

public class Human{

}

在使用 @Component 注釋后,Spring 容器必須啟用類掃描機制以啟用注釋驅動 Bean 定義和注釋驅動 Bean 自動注入的策略。Spring 2.5 對 context 命名空間進行了擴展,提供了這一功能,請看下面的配置:

Xml代碼 <?xml version="1.0" encoding="UTF-8" ?>

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

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

xsi:schemaLocation="http://www.springframework.org/schema/beans

參考資料:

總結

以上是生活随笔為你收集整理的java调用外联服务用xml,Spring IOC 依赖注入的两种方式:XML和注解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。