2014-03-19 17 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)如果你在非抽象类中定义了这样的方法,那么你必须使这个类抽象。 为了避免这种强制更改,提供一个身体更为方便。

相关问题