001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.camel.spring.spi;
018
019import java.lang.reflect.Method;
020import java.lang.reflect.Modifier;
021
022import org.apache.camel.RuntimeCamelException;
023import org.apache.camel.spi.Injector;
024import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
025import org.springframework.context.ConfigurableApplicationContext;
026
027/**
028 * A Spring implementation of {@link Injector} allowing Spring to be used to dependency inject newly created POJOs
029 */
030public class SpringInjector implements Injector {
031    private final ConfigurableApplicationContext applicationContext;
032    private int autowireMode = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
033    private boolean dependencyCheck;
034
035    public SpringInjector(ConfigurableApplicationContext applicationContext) {
036        this.applicationContext = applicationContext;
037    }
038
039    public <T> T newInstance(Class<T> type) {
040        return newInstance(type, true);
041    }
042
043    @Override
044    public <T> T newInstance(Class<T> type, String factoryMethod) {
045        T answer = null;
046        try {
047            // lookup factory method
048            Method fm = type.getMethod(factoryMethod);
049            if (Modifier.isStatic(fm.getModifiers()) && Modifier.isPublic(fm.getModifiers()) && fm.getReturnType() == type) {
050                Object obj = fm.invoke(null);
051                answer = type.cast(obj);
052            }
053        } catch (Exception e) {
054            throw new RuntimeCamelException("Error invoking factory method: " + factoryMethod + " on class: " + type, e);
055        }
056        return answer;
057    }
058
059    @Override
060    public <T> T newInstance(Class<T> type, boolean postProcessBean) {
061        Object value;
062        if (postProcessBean) {
063            value = applicationContext.getBeanFactory().createBean(type, autowireMode, dependencyCheck);
064        } else {
065            value = applicationContext.getBeanFactory().createBean(type, AutowireCapableBeanFactory.AUTOWIRE_NO, false);
066        }
067        return type.cast(value);
068    }
069
070    @Override
071    public boolean supportsAutoWiring() {
072        return true;
073    }
074
075    public int getAutowireMode() {
076        return autowireMode;
077    }
078
079    public void setAutowireMode(int autowireMode) {
080        this.autowireMode = autowireMode;
081    }
082
083    public boolean isDependencyCheck() {
084        return dependencyCheck;
085    }
086
087    public void setDependencyCheck(boolean dependencyCheck) {
088        this.dependencyCheck = dependencyCheck;
089    }
090
091    public ConfigurableApplicationContext getApplicationContext() {
092        return applicationContext;
093    }
094}