/** * Copyright (c) 2016, biezhi 王爵 (biezhi.me@gmail.com) * <p> * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.blade.ioc; import com.blade.ioc.loader.IocLoader; import com.blade.kit.Assert; import com.blade.kit.IocKit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.reflect.Modifier; import java.util.*; /** * The default IOC container implementation * * @author <a href="mailto:biezhi.me@gmail.com" target="_blank">biezhi</a> * @since 1.5 */ public class SimpleIoc implements Ioc { private static final Logger LOGGER = LoggerFactory.getLogger(Ioc.class); private final Map<String, BeanDefine> pool = new HashMap<>(32); /** * ioc loader */ @Override public void load(IocLoader loader) { loader.load(this); } /** * Add user-defined objects */ @Override public void addBean(Object bean) { Assert.notNull(bean); addBean(bean.getClass().getName(), bean); } /** * Add user-defined objects */ public void addBean(Class<?> beanClass, Object bean) { Assert.notNull(beanClass); addBean(beanClass.getName(), bean); } /** * Add user-defined objects */ public void addBean(String name, Object bean) { Assert.notNull(bean); BeanDefine beanDefine = new BeanDefine(bean); addBean(name, beanDefine); // add interface Class<?>[] interfaces = beanDefine.getType().getInterfaces(); if (interfaces.length > 0) { for (Class<?> interfaceClazz : interfaces) { this.addBean(interfaceClazz.getName(), beanDefine); } } } /** * Update BeanDefine */ public void setBean(Class<?> type, Object proxyBean) { Assert.notNull(proxyBean); BeanDefine beanDefine = pool.get(type.getName()); if (beanDefine != null) { beanDefine.setBean(proxyBean); } else { beanDefine = new BeanDefine(proxyBean, type); } pool.put(type.getName(), beanDefine); } /** * Add user-defined objects */ public void addBean(String name, BeanDefine beanDefine) { Assert.notNull(name); Assert.notNull(beanDefine); // LOGGER.debug("addBean: {}", name); if (pool.put(name, beanDefine) != null) { LOGGER.warn("Duplicated Bean: {}", name); } } /** * Register @Component marked objects */ @Override public Object addBean(Class<?> type) { return addBean(type, true); } /** * Register @Component marked objects */ public Object addBean(Class<?> type, boolean singleton) { Assert.notNull(type); return addBean(type.getName(), type, singleton); } /** * Register @Component marked objects */ public Object addBean(String name, Class<?> beanClass, boolean singleton) { Assert.notNull(name); Assert.notNull(beanClass); Assert.isFalse(beanClass.isInterface(), "Must not be interface: %s", beanClass.getName()); Assert.isFalse(Modifier.isAbstract(beanClass.getModifiers()), "Must not be abstract class: %s", beanClass.getName()); // LOGGER.debug("addBean: {} = {}", name, beanClass.getName()); BeanDefine beanDefine = this.getBeanDefine(beanClass, singleton); if (pool.put(name, beanDefine) != null) { LOGGER.warn("Duplicated Bean: {}", name); } // add interface Class<?>[] interfaces = beanClass.getInterfaces(); if (interfaces.length > 0) { for (Class<?> interfaceClazz : interfaces) { if (null != this.getBean(interfaceClazz)) { break; } this.addBean(interfaceClazz.getName(), beanDefine); } } return beanDefine.getBean(); } public BeanDefine getBeanDefine(Class<?> beanClass, boolean singleton) { try { Object object = beanClass.newInstance(); return new BeanDefine(object, beanClass, singleton); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; } @Override public <T> T getBean(Class<T> type) { Object bean = this.getBean(type.getName()); try { return type.cast(bean); } catch (Exception e) { e.printStackTrace(); } return null; } @Override public Object getBean(String name) { BeanDefine beanDefine = pool.get(name); if (beanDefine == null) { return null; } return IocKit.getBean(beanDefine); } @Override public List<BeanDefine> getBeanDefines() { return new ArrayList<BeanDefine>(pool.values()); } @Override public List<Object> getBeans() { Set<String> beanNames = this.getBeanNames(); List<Object> beans = new ArrayList<Object>(beanNames.size()); for (String beanName : beanNames) { Object bean = this.getBean(beanName); if (null != bean) { beans.add(bean); } } return beans; } @Override public Set<String> getBeanNames() { return pool.keySet(); } @Override public void remove(String beanName) { pool.remove(beanName); } @Override public void remove(Class<?> type) { pool.remove(type.getSimpleName()); } @Override public void clearAll() { pool.clear(); } }