Если нельзя, но очень хочется, то нужно обязательно и ничего в мире не стоит того, чтобы делать из этого проблему!


Интересна Java? Кликай по ссылке и изучай!
Если тебе полезно что-то из того, чем я делюсь в своем блоге - можешь поделиться своими деньгами со мной.
с пожеланием
столько времени читатели провели на блоге - 
сейчас онлайн - 

суббота, 30 октября 2010 г.

Java for fun: Spring IoC для бедных

Spring IoC контейнер для бедных:

/**
  * Метод служит для инъекции одного объекта в соответствующие поля другого. 
  * Все поля, которые могут принять этот объект да заполнятся им (окромя Object).    
  * @param object Кого укалываем. 
  * @param injectible Что вводим. 
  * @return вернули то, что дали на вход (удобства ради).
  */
 <T> T injectAll(T object, Object injectible);
Если надо это чудо - читаем дальше...

package utils;

import java.lang.reflect.Field;

public final class Injector {

 /**
  * Метод служит для инъекции одного объекта в соответствующие поля другого. 
  * Все поля, которые могут принять этот объект да заполнятся им (окромя Object).    
  * @param object Кого укалываем. 
  * @param injectible Что вводим. 
  * @return вернули то, что дали на вход (удобства ради).
  */
 public static <T> T injectAll(T object, Object injectible) 
 {
     final Field[] declaredFields = object.getClass().getDeclaredFields();
        final Class injectibleClass = injectible.getClass();
        
        boolean injected = false;
        
        for (Field field : declaredFields) {
            if (Object.class.equals(field.getType())) {
                continue;
            }
            
            if (!field.getType().isAssignableFrom(injectibleClass)) {
                continue;
            }
            
            field.setAccessible(true);
            
            try {
                field.set(object, injectible);
            } catch (IllegalArgumentException e) {
                throw new IllegalArgumentException("Неудача, по причине:", e);
            } catch (IllegalAccessException e) {
                throw new IllegalArgumentException("Неудача, по причине:", e);
            }
            
            field.setAccessible(false);
            
            injected = true;
        }
        
        if (!injected) {
            throw new IllegalArgumentException("В исходном объекте не нашлось ни одного поля по образу и подобию.");
        }
        
        return object;
    }
}
Аминь!..

Кто не верует, вот тест чудотворный
package test.utils;

import static org.junit.Assert.*;

import org.junit.Test;

import utils.Injector;

public class InjectorTest {

    class Injectable {        
    }
    
    class FieldWithSameClass {                
        private Injectable object = null;          
    }
        
    @Test
    public void testInjectObjectInTheFieldWithSameClass() {                
        assertNotNull(Injector.injectAll(new FieldWithSameClass(), 
                new Injectable()).object);
    }
    
    class FieldsWithSameClass {                
        private Injectable object1 = null;          
        private Injectable object2 = null;
    }
    
    @Test
    public void testMultipleInjectionInTheFieldsWithSameClass() {                
        final Injectable injectable = new Injectable();
        FieldsWithSameClass source = 
                Injector.injectAll(new FieldsWithSameClass(), injectable);
        
        assertNotNull(source.object1);
        assertNotNull(source.object2);
        assertSame(injectable, source.object1);
        assertSame(source.object1, source.object2);    
    }
    
    class InjectableWithInterface implements InjectableI {        
    }
    
    interface InjectableI {        
    }
    
    class FieldWithClassImplementsInterface {                
        private InjectableWithInterface object = null;          
    }
    
    @Test
    public void testInjectObjectInTheFieldWithClassImplementsInterface() {                
        assertNotNull(Injector.injectAll(new FieldWithClassImplementsInterface(), 
                new InjectableWithInterface()).object);
    }
    
    class FieldWithInterface {                
        private InjectableI object = null;          
    }
    
    @Test
    public void testInjectObjectInTheFieldWithInterface() {                
        final InjectableI injectable = new InjectableWithInterface();
        assertNotNull(Injector.injectAll(new FieldWithInterface(), 
                injectable).object);
    }
    
    class InjectableParent {        
    }
    
    class InjectableChild extends InjectableParent {        
    }
    
    class FieldWithExtends {                
        private InjectableParent object = null;          
    }
    
    @Test
    public void testInjectObjectInTheFieldWithExtends_injectChild() {                
        assertNotNull(Injector.injectAll(new FieldWithExtends(), 
                new InjectableChild()).object);
    }
    
    @Test
    public void testInjectObjectInTheFieldWithExtends_injectParent() {                
        assertNotNull(Injector.injectAll(new FieldWithExtends(), 
                new InjectableParent()).object);
    }
    
    class FieldWithObject {
        private Object object1;
        private Injectable object2;
    }
    
    @Test
    public void testNoObjectInjection() {                
        final FieldWithObject source = 
            Injector.injectAll(new FieldWithObject(), new Injectable());
        assertNull(source.object1);
        assertNotNull(source.object2);
    }
    
    class FieldWithObjectOnly {
        private Object object;    
    }
    
    @Test
    public void testNoInjectionExceptionIfObjectPresent() {                
        try {
            Injector.injectAll(new FieldWithObjectOnly(), new Injectable());
            fail("Бес попутал, должон быть exception");
        } catch (IllegalArgumentException e) {
            assertEquals("В исходном объекте не нашлось ни одного поля по образу и подобию.", 
                    e.getMessage());
        }
    }
    
    class FieldWithoutObjects {
    }
    
    @Test
    public void testNoInjectionExceptionIfNoObjects() {                
        try {
            Injector.injectAll(new FieldWithoutObjects(), new Injectable());
            fail("Бес попутал, должон быть exception");
        } catch (IllegalArgumentException e) {
            assertEquals("В исходном объекте не нашлось ни одного поля по образу и подобию.", 
                    e.getMessage());
        }
    }    
}

4 комментария:

  1. А мож таки правильней:

    if ( ! Object.class.equals(field.getType()) ) {
    continue;
    }

    а то как то без "!" ведь будет пропускать именно нужные поля.
    Или я не понял задумки партии и правительства ?

    ОтветитьУдалить
  2. Посмотрите, пожалуйста тест testNoObjectInjection - там описана задумка.

    ОтветитьУдалить
  3. Ответы
    1. Так жеж все обадвое класса в посте. Я не уверен что найду сейчас его. Плиз скопируй их и если что не так, и не получается исправить - пиши, буду искать

      Удалить