2014-03-19 19 views
1

我正在閱讀春季http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/beans.html#beans-factory-method-injectionLookup method injection的文章。Spring中的查找方法注入

在此,有一個說法

If the method is abstract, the dynamically-generated subclass implements the method. 
Otherwise, the dynamically-generated subclass overrides the concrete method defined in the original class. 

我不明白這些two.Can有人請用一個例子解釋之間的區別?

回答

0

這是Spring使用CGLib的地方。這並不重要 - 關鍵是你應該理解Spring正在創建一個將該實例交給客戶端的代理對象。

即代理對象,這彈簧產生您使用CGLIB爲,既可以實現一個抽象方法,或倍率的具體方法。所以它檢查你的類是否提供了一個標記爲抽象的方法,或者如果你提供了一個沒有標記爲抽象的方法(因此你的方法將被覆蓋)。

代理用於不同的容器。它們在Java Enterprise世界的運行時也很常見。如果您的類可能被一個運行時代理子類化,那麼如果您還想要一個帶參數的公共構造函數,則會發現您需要提供一個無參數構造函數(非公共構造函數很好)。

+0

謝謝..但是如果我提供抽象或非抽象方法,會產生什麼樣的差異?任何優點/缺點? – Anand

2
Lookup Method DI:- 

What is Lookup Method- 
Here lookup method means 
if a method, if it is not having any implementation or 
if a method, if it is required any depedency we can consider that method as a lookup method. 

for ex. 
1. In case of interface 

interface Test{ 

public void a(); //lookup method 
public void b(); //lookup method 

} 

2. In case of abstract class 

abstract class Test{ 

    abstract public void a(); //lookup method 

    public void b(){ 

    } 
} 

3. In case of concrete class 

class Test{ 

/* if you want to override method a() then you can call this method also like lookup method */ 
    public void a(){ 
     //implementation 
    } 

    public void b(){ 
     //implementation 
    } 
} 

Note:-if you want to provide implementation to that method you can call that method as lookup method. 

By using spring you can provide implementation, 
for abstract classes you can provide implementation, 
for interface you can provide implementation and 
in case if you don’t satisfy existing implementation from concreate class that implementation also you can override. 

**Example:-** 

*Required jar file 
commons-logging-1.1.3.jar 
org.springframework.asm-3.0.1.RELEASE-A.jar 
org.springframework.beans-3.0.1.RELEASE-A.jar 
org.springframework.context-3.0.1.RELEASE-A.jar 
org.springframework.core-3.0.1.RELEASE-A.jar 
org.springframework.expression-3.0.1.RELEASE-A.jar 
cglib-nodep-2.2.jar :- cglib jar will help to generate runtime proxy. 

**Engine class** 

package beans; 

public class Engine { 
    private String name; 

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

**Car interface** 

package beans; 

public interface Car { 

    //return Engine class object 
    public Engine myCarEngine(); 
} 

**Bus abstract class** 

package beans; 

abstract public class Bus { 

    //return Engine class object 
    abstract public Engine myBusEngine(); 
} 

**Truk concrete class** 

package beans; 

public class Truck { 

    //if you don't satisfy this existing implementation you can override by using lookup method. 
    public Engine myTrukEngine(){ 
     Engine e=new Engine(); 
     e.setName("Eicher-Truck"); 
     return e; 
    } 
} 

**spring.xml** 

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> 

<beans> 

    <!-- for car interface provide lookup method --> 
    <bean id="c" class="beans.Car"> 
     <lookup-method name="myCarEngine" bean="e" /> 
    </bean> 
    <bean id="e" class="beans.Engine"> 
     <property name="name" value="swift Car Engine" /> 
    </bean> 


    <!-- for bus abstract provide lookup method --> 
    <bean id="b" class="beans.Bus"> 
     <lookup-method name="myBusEngine" bean="e1" /> 
    </bean> 
    <bean id="e1" class="beans.Engine"> 
     <property name="name" value="TATA BusEngine" /> 
    </bean> 


    <!-- for Truck concrete provide lookup method --> 
    <bean id="t" class="beans.Truck"> 
     <lookup-method name="myTrukEngine" bean="e2" /> 
    </bean> 
    <bean id="e2" class="beans.Engine"> 
     <property name="name" value="BENZ Truck Engine" /> 
    </bean> 

</beans> 

**Client class** 

package test; 

import java.util.*; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.support.ClassPathXmlApplicationContext; 

import beans.Bus; 
import beans.Car; 
import beans.Truck; 

public class Client { 

    public static void main(String[] args) { 

     ApplicationContext ap= new ClassPathXmlApplicationContext("resource/spring.xml"); 
     System.out.println("-----------Car----------"); 
     Car c=(Car)ap.getBean("c"); 
     System.out.println("Name of Class generated by spring at runtime="+c.getClass().getCanonicalName()); 
     System.out.println("Engine Name="+c.myCarEngine().getName()); 

     System.out.println("-----------Bus----------"); 
     Bus b=(Bus)ap.getBean("b"); 
     System.out.println("Name of Class generated by spring at runtime="+b.getClass().getCanonicalName()); 
     System.out.println("Engine Name="+b.myBusEngine().getName()); 

     System.out.println("-----------Truk----------"); 
     Truck t=(Truck)ap.getBean("t"); 
     System.out.println("Name of Class generated by spring at runtime="+t.getClass().getCanonicalName()); 
     System.out.println("Engine Name="+t.myTrukEngine().getName()); 

    } 


} 

**OutPut:-** 

———–Car———- 
Name of Class generated by spring at runtime=beans.Car$$EnhancerByCGLIB$$68fda491 
Engine Name=swift Car Engine 

———–Bus———- 
Name of Class generated by spring at runtime=beans.Bus$$EnhancerByCGLIB$$cfce5a7 
Engine Name=TATA BusEngine 

———–Truk———- 
Name of Class generated by spring at runtime=beans.Truck$$EnhancerByCGLIB$$dc82ada3 
Engine Name=BENZ Truck Engine 

How to spring provide implementation :- 
if we load spring.xml file into Ioc Container ,then Ioc container generate runtime proxy class by using cglib jar for provide implementation. 
like.. 


//This class generate by Spring at runtime 
class CarProxy extends Car{ 
    @Override 
    public Engine myCarEngine(){ 

     //implementation 
     return e; 
    } 
} 
0

我認爲不同之處在於一般的概念是不提供任何lookup-method的實現,因爲你希望注入它。但是,這會導致您遇到問題: 1)如果您在已經抽象的類中將此方法定義爲抽象,那麼您的子類必須實現它。 2)如果你在非抽象類中定義了這樣的方法,那麼你必須使這個類抽象。 爲了避免這種強制更改,提供一個身體更爲方便。

相關問題