/* * Copyright 2008-2009 the original author or authors. * * 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 * * http://www.apache.org/licenses/LICENSE-2.0 * * 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 net.hasor.core.binder; import net.hasor.core.*; import net.hasor.core.classcode.matcher.AopMatchers; import net.hasor.core.container.BeanBuilder; import net.hasor.core.container.ScopManager; import net.hasor.core.info.AopBindInfoAdapter; import net.hasor.core.provider.InstanceProvider; import net.hasor.core.utils.BeanUtils; import net.hasor.core.utils.StringUtils; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.List; import java.util.Set; import java.util.UUID; /** * 标准的 {@link ApiBinder} 接口实现,Hasor 在初始化模块时会为每个模块独立分配一个 ApiBinder 接口实例。 * <p>抽象方法 {@link #getBeanBuilder()} ,会返回一个类( {@link BeanBuilder} )用于配置Bean信息。 * @version : 2013-4-12 * @author 赵永春 (zyc@hasor.net) */ public abstract class AbstractBinder implements ApiBinder { private Environment environment; public AbstractBinder(Environment environment) { this.environment = Hasor.assertIsNotNull(environment, "environment is null."); } // @Override public Environment getEnvironment() { return this.environment; } @Override public Set<Class<?>> findClass(final Class<?> featureType) { String[] spanPackage = this.getEnvironment().getSpanPackage(); return this.getEnvironment().findClass(featureType, spanPackage); } @Override public Set<Class<?>> findClass(Class<?> featureType, String... scanPackages) { if (featureType == null || scanPackages == null || scanPackages.length == 0) { return null; } return this.getEnvironment().findClass(featureType, scanPackages); } @Override public void installModule(final Module module) throws Throwable { //see : net.hasor.core.binder.ApiBinderInvocationHandler.invoke() throw new IllegalStateException("current state is not allowed."); } @Override public <T extends ApiBinder> T tryCast(Class<T> castApiBinder) { //see : net.hasor.core.binder.ApiBinderInvocationHandler.invoke() throw new IllegalStateException("current state is not allowed."); } // /*------------------------------------------------------------------------------------Binding*/ protected Class<?> getBinderSource() { return ApiBinder.class; } /**注册一个类型*/ protected abstract BeanBuilder getBeanBuilder(); /**注册一个类型*/ protected abstract ScopManager getScopManager(); // @Override public <T> NamedBindingBuilder<T> bindType(final Class<T> type) { BeanBuilder builder = this.getBeanBuilder(); BindInfoBuilder<T> typeBuilder = builder.createInfoAdapter(type, this.getBinderSource()); return new BindingBuilderImpl<T>(typeBuilder); } @Override public <T> MetaDataBindingBuilder<T> bindType(final Class<T> type, final T instance) { return this.bindType(type).toInstance(instance); } @Override public <T> InjectPropertyBindingBuilder<T> bindType(final Class<T> type, final Class<? extends T> implementation) { return this.bindType(type).to(implementation); } @Override public <T> ScopedBindingBuilder<T> bindType(final Class<T> type, final Provider<T> provider) { return this.bindType(type).toProvider(provider); } @Override public <T> InjectPropertyBindingBuilder<T> bindType(final String withName, final Class<T> type) { return this.bindType(type).nameWith(withName).to(type); } @Override public <T> MetaDataBindingBuilder<T> bindType(final String withName, final Class<T> type, final T instance) { return this.bindType(type).nameWith(withName).toInstance(instance); } @Override public <T> InjectPropertyBindingBuilder<T> bindType(final String withName, final Class<T> type, final Class<? extends T> implementation) { return this.bindType(type).nameWith(withName).to(implementation); } @Override public <T> LifeBindingBuilder<T> bindType(final String withName, final Class<T> type, final Provider<T> provider) { return this.bindType(type).nameWith(withName).toProvider(provider); } // @Override public Provider<Scope> registerScope(String scopeName, Provider<Scope> scope) { return this.getScopManager().registerScope(scopeName, scope); } @Override public Provider<Scope> registerScope(String scopeName, Scope scope) { return this.registerScope(scopeName, new InstanceProvider<Scope>(scope)); } /*----------------------------------------------------------------------------------------Aop*/ // static { // final String tmpWordReg = "[^\\s,]+"; // final String tmpParamsReg = "(?:(?:W *, *){0,}W)?"; // final String tmpMethodReg = "(W) (W.W)\\((P)\\)"; // String methodReg = tmpMethodReg.replace("P", tmpParamsReg).replace("W", tmpWordReg); // InterceptorPattern = java.util.regex.Pattern.compile(methodReg); // } // private static final Pattern InterceptorPattern; @Override public void bindInterceptor(final String matcherExpression, final MethodInterceptor interceptor) { // Matcher<Class<?>> matcherClass = AopMatchers.expressionClass(matcherExpression); Matcher<Method> matcherMethod = AopMatchers.expressionMethod(matcherExpression); this.bindInterceptor(matcherClass, matcherMethod, interceptor); } @Override public void bindInterceptor(final Matcher<Class<?>> matcherClass, final Matcher<Method> matcherMethod, final MethodInterceptor interceptor) { Hasor.assertIsNotNull(matcherClass, "matcherClass is null."); Hasor.assertIsNotNull(matcherMethod, "matcherMethod is null."); Hasor.assertIsNotNull(interceptor, "interceptor is null."); // AopBindInfoAdapter aopAdapter = new AopBindInfoAdapter(matcherClass, matcherMethod, interceptor); aopAdapter = Hasor.autoAware(this.getEnvironment(), aopAdapter); this.bindType(AopBindInfoAdapter.class).uniqueName().toInstance(aopAdapter); } @Override public <T> List<BindInfo<T>> findBindingRegister(Class<T> bindType) { Hasor.assertIsNotNull(bindType, "bindType is null."); return getBeanBuilder().findBindInfoList(bindType); } @Override public <T> BindInfo<T> findBindingRegister(String withName, Class<T> bindType) { Hasor.assertIsNotNull(withName, "withName is null."); Hasor.assertIsNotNull(bindType, "bindType is null."); return getBeanBuilder().findBindInfo(withName, bindType); } @Override public <T> BindInfo<T> getBindInfo(String bindID) { Hasor.assertIsNotNull(bindID, "bindID is null."); return getBeanBuilder().findBindInfoByID(bindID); } @Override public <T> BindInfo<T> getBindInfo(Class<T> bindType) { Hasor.assertIsNotNull(bindType, "bindType is null."); return getBeanBuilder().findBindInfoByType(bindType); } // /*------------------------------------------------------------------------------------Binding*/ /** 一堆接口的实现 */ private class BindingBuilderImpl<T> implements // InjectConstructorBindingBuilder<T>, InjectPropertyBindingBuilder<T>, // NamedBindingBuilder<T>, LinkedBindingBuilder<T>, LifeBindingBuilder<T>, ScopedBindingBuilder<T>, MetaDataBindingBuilder<T> { private BindInfoBuilder<T> typeBuilder = null; private Class<?>[] initParams = new Class<?>[0]; // public BindingBuilderImpl(final BindInfoBuilder<T> typeBuilder) { this.typeBuilder = typeBuilder; } @Override public LifeBindingBuilder<T> initMethod(String methodName) { this.typeBuilder.initMethod(methodName); return this; } @Override public MetaDataBindingBuilder<T> metaData(final String key, final Object value) { this.typeBuilder.setMetaData(key, value); return this; } @Override public MetaDataBindingBuilder<T> asEagerPrototype() { this.typeBuilder.setSingleton(false); return this; } @Override public MetaDataBindingBuilder<T> asEagerSingleton() { this.typeBuilder.setSingleton(true); return this; } @Override public NamedBindingBuilder<T> idWith(String newID) { if (!StringUtils.isBlank(newID)) { this.typeBuilder.setBindID(newID); this.typeBuilder.setBindName(newID); } return this; } @Override public LinkedBindingBuilder<T> nameWith(final String name) { this.typeBuilder.setBindName(name); return this; } @Override public LinkedBindingBuilder<T> uniqueName() { this.typeBuilder.setBindName(UUID.randomUUID().toString()); return this; } @Override public MetaDataBindingBuilder<T> toScope(final Scope scope) { return this.toScope(new InstanceProvider<Scope>(scope)); } @Override public MetaDataBindingBuilder<T> toInstance(final T instance) { return this.toProvider(new InstanceProvider<T>(instance)); } @Override public InjectPropertyBindingBuilder<T> to(final Class<? extends T> implementation) { this.typeBuilder.setSourceType(implementation); return this; } @Override public InjectConstructorBindingBuilder<T> toConstructor(final Constructor<? extends T> constructor) { Class<? extends T> targetType = constructor.getDeclaringClass(); //因为设置了构造方法因此重新设置SourceTypeF this.typeBuilder.setSourceType(targetType); // Class<?>[] params = constructor.getParameterTypes(); if (params != null) { for (int i = 0; i < params.length; i++) { Object defaultValue = BeanUtils.getDefaultValue(params[i]);//取得参数的默认值 this.typeBuilder.setConstructor(i, params[i], new InstanceProvider<Object>(defaultValue)); } this.initParams = params; } return this; } @Override public MetaDataBindingBuilder<T> toScope(final Provider<Scope> scope) { this.typeBuilder.setScopeProvider(scope); return this; } @Override public MetaDataBindingBuilder<T> toScope(String scopeName) { return this.toScope(getScopManager().findScope(scopeName)); } @Override public LifeBindingBuilder<T> toProvider(final Provider<? extends T> provider) { if (provider != null) { this.typeBuilder.setCustomerProvider(provider); } return this; } // @Override public InjectPropertyBindingBuilder<T> injectValue(final String property, final Object value) { return this.inject(property, new InstanceProvider<Object>(value)); } @Override public InjectPropertyBindingBuilder<T> inject(final String property, final BindInfo<?> valueInfo) { this.typeBuilder.addInject(property, valueInfo); return this; } @Override public InjectPropertyBindingBuilder<T> inject(final String property, final Provider<?> valueProvider) { this.typeBuilder.addInject(property, valueProvider); return this; } @Override public InjectConstructorBindingBuilder<T> injectValue(final int index, final Object value) { return this.inject(index, new InstanceProvider<Object>(value)); } @Override public InjectConstructorBindingBuilder<T> inject(final int index, final BindInfo<?> valueInfo) { if (index >= this.initParams.length) { throw new IndexOutOfBoundsException("index out of bounds."); } this.typeBuilder.setConstructor(index, this.initParams[index], valueInfo); return this; } @Override public InjectConstructorBindingBuilder<T> inject(final int index, final Provider<?> valueProvider) { if (index >= this.initParams.length) { throw new IndexOutOfBoundsException("index out of bounds."); } this.typeBuilder.setConstructor(index, this.initParams[index], valueProvider); return this; } @Override public BindInfo<T> toInfo() { return this.typeBuilder.toInfo(); } } // }