Метод поиска инъекций в Spring

1

Я читал статью о Lookup method injection в Spring 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.

Я не понял разницы между этими двумя. Может кто-нибудь объяснить пример?

Теги:
spring
dependency-injection

4 ответа

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 dont 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

В Multi Threading Environment у вас есть требование, например, вы хотите вставлять прототип bean-компонента в Single ton bean, но весна будет возвращать один объект только для одного компонента, когда область bean-компонента является singleton.then Prototype не будет работать, она будет действовать как singleton, потому что она была введена один раз весенним контейнером IOC. В это время мы будем искать метод инъекций, предоставленный Spring.By с помощью метода подбора метода поиска, мы получим одноэлементный объект с инъецированным новым объектом Prototype каждый раз, когда вы вызываете. Но как это получится...? Теперь вы получите ответ на свой вопрос, когда вы сконфигурируете свой идентификатор компонента прототипа в качестве метода поиска в файле SpringBeanConfiguratipon, Internally spring создаст класс Prototype $ Proxy из расширения класса Prototype и переопределит ваш метод поиска. если ваш метод поиска является абстрактным, он будет реализовывать иначе переопределить. Когда вы вызываете метод поиска, он вызывает метод класса Proxy, и он будет давать каждый раз новый объект.

0

Я считаю, что разница заключается в том, что общая концепция заключается в том, чтобы не предоставлять какую-либо реализацию lookup-метода, поскольку вы хотите, чтобы она была введена. Но это приводит к возникновению проблемы: 1) Если вы определяете этот метод как абстрактный в классе, который уже является абстрактным, то ваши подклассы должны его реализовать. 2) Если вы определяете такой метод в не-абстрактном классе, вы должны сделать этот класс абстрактным. Чтобы избежать таких принудительных изменений, удобнее обеспечить тело.

0

Именно здесь Spring использует CGLib. Это не важно - дело в том, что вы должны понимать, что Spring создает прокси-объект, передающий этот экземпляр вашим клиентам.

Этот прокси-объект, который Spring генерирует для вас с помощью CGLib, может либо реализовать абстрактный метод, либо переопределить конкретный метод. Поэтому он исследует ваш класс для разработки, если вы поставляете метод, который помечен как абстрактный, или если вы предоставили метод, который не помечен как абстрактный (и, следовательно, ваш метод будет отменен).

Прокси используются в нескольких контейнерах. Они также распространены во время работы в мире Java Enterprise. Если ваш класс может быть подклассифицирован прокси-сервером времени выполнения, вы обнаружите, что вам нужно предоставить конструктор no-args (непубличный в порядке), если вы также хотите создать публичный конструктор с аргументами.

  • 0
    Спасибо ... но какая разница, если я предоставлю абстрактный или не абстрактный метод? какие-то плюсы / минусы?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню