java - Spring中的Lookup方法注入(inject)

标签 java spring dependency-injection

我正在阅读有关Spring中Lookup方法注入(inject)的文章http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/beans.html#beans-factory-method-injection .

这里有一个声明

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.

我不明白这两者之间的区别。有人可以举例说明吗?

最佳答案

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;
    }
}

关于java - Spring中的Lookup方法注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22502854/

相关文章:

java - 无法解决属性(property)问题

java - Android 上的 SSL TCP 连接(带证书)

Java - 组合两个数组?

java - Spring集成异步流程

java - 我应该如何修复找不到所需类型的 bean?

java - Guice 配置/绑定(bind)最佳实践

grails - 如何将springSecurityService注入(inject)自定义监听器

Java FMJ 不是跨平台的吗?如何修复?

java - 用于内部方法和私有(private)方法的 AOP Java

C# - 将 Unity 添加到我的 Visual Studio 项目?