com.helpinput.spring.BeanRegister.java Source code

Java tutorial

Introduction

Here is the source code for com.helpinput.spring.BeanRegister.java

Source

/*
 * Copyright 2013-2015 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.
 */

/**
 *@Author: niaoge(Zhengsheng Xia)
 *@Email 78493244@qq.com
 *@Date: 2015-6-16
 */
package com.helpinput.spring;

import static com.helpinput.spring.Consts.ApplicatoinScoped;
import static com.helpinput.spring.Consts.FlashScoped;
import static com.helpinput.spring.Consts.Prototype;
import static com.helpinput.spring.Consts.RequestScoped;
import static com.helpinput.spring.Consts.SessionScoped;
import static com.helpinput.spring.Consts.Singleton;
import static com.helpinput.spring.Consts.ViewScoped;
import static com.helpinput.spring.Consts.application_scope;
import static com.helpinput.spring.Consts.flash_scope;
import static com.helpinput.spring.Consts.prototype_scope;
import static com.helpinput.spring.Consts.relativePath;
import static com.helpinput.spring.Consts.request_scope;
import static com.helpinput.spring.Consts.session_scope;
import static com.helpinput.spring.Consts.singleton_scope;
import static com.helpinput.spring.Consts.view_scope;

import java.beans.PropertyEditor;
import java.lang.annotation.Annotation;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Scope;
import org.springframework.context.support.AbstractApplicationContext;

import com.helpinput.core.Utils;
import com.helpinput.holder.ContextHolder;
import com.helpinput.propertyeditors.PropertyEditorRegister;
import com.helpinput.spring.refresher.ContextRefresher;
import com.helpinput.spring.registinerceptor.BeanRegistInterceptor;

public class BeanRegister {
    static Logger logger = LoggerFactory.getLogger(BeanRegister.class);

    enum Info {
        Registed, Updated, Removed;
    }

    private static void logRegist(Info info, String relativePath, String beanName, String scope) {
        System.out.println(
                info.name() + " bean [" + beanName + "] of [scope: " + scope + "] in file [" + relativePath + "]");
    }

    static String findScopeStr(Class<?> clz) {
        String result = null;
        if (clz != null && clz != Object.class) {
            Annotation[] annotations = clz.getDeclaredAnnotations();
            for (int i = annotations.length - 1; i >= 0; i--) {
                Annotation annotation = annotations[i];
                String simpleName = annotation.annotationType().getSimpleName();

                if (RequestScoped.equals(simpleName))
                    return request_scope;
                else if (FlashScoped.equals(simpleName))
                    return flash_scope;
                else if (ViewScoped.equals(simpleName))
                    return view_scope;
                else if (SessionScoped.equals(simpleName))
                    return session_scope;
                else if (ApplicatoinScoped.equals(simpleName))
                    return application_scope;
                else if (Singleton.equals(simpleName))
                    return singleton_scope;
                else if (Prototype.equals(simpleName))
                    return prototype_scope;

                else if (annotation instanceof Scope) {
                    Scope scopeAnn = (Scope) annotation;
                    if (Utils.hasLength(scopeAnn.value()))
                        return scopeAnn.value();
                }
            }
            result = findScopeStr(clz.getSuperclass());
        }
        if (Utils.hasLength(result))
            return result;
        return singleton_scope;
    }

    /** aop */
    /*
     * private static boolean checkInterceptor(Class<?> clz) { if (clz == null)
     * return false; Method[] methods = clz.getDeclaredMethods(); for (Method
     * method : methods) { //classHandled  PostValidate ?? if
     * (method.getAnnotation(Handled.class) != null ||
     * method.getAnnotation(PostValidate.class) != null) { return true; } }
     * return checkInterceptor(clz.getSuperclass()); }
     */

    public static BeanDefinitionBuilder createBuilder(Class<?> clz, Class<?> InterceptorClass) {
        /** aop */
        /*
         * if (InterceptorClass != null) { if (checkInterceptor(clz)) {
         * BeanDefinitionBuilder builder =
         * BeanDefinitionBuilder.rootBeanDefinition(InterceptorClass,
         * "getInstance"); builder.addConstructorArgValue(clz); return builder;
         * } }
         */
        return BeanDefinitionBuilder.rootBeanDefinition(clz);
    }

    public static BeanDefinitionWrap registerBean(ApplicationContext context, DefaultListableBeanFactory dlbf,
            BeanDefinitionBuilder builder, Class<?> clz, String beanName, String scope, BeanInfo beanInfo) {
        if (!Utils.hasLength(beanName)) {
            beanName = Commons.getBeanName(clz);
            if (!Utils.hasLength(beanName))
                beanName = Utils.beanName(beanInfo.scanName);
        }

        if (!Utils.hasLength(beanName))
            return null;

        //bean?bean
        if (beanName.endsWith("Impl")) {
            beanName = beanName.substring(0, beanName.length() - 4);
        }

        if (!Utils.hasLength(beanName))
            return null;

        removeBean(dlbf, beanInfo, null);

        BeanDefinition bd = null;
        if (!Utils.hasLength(scope))
            scope = findScopeStr(clz);

        List<BeanRegistInterceptor> interceptors = ContextHolder.beanRegistIntercpterHolder.getList();
        if (Utils.hasLength(interceptors)) {
            for (BeanRegistInterceptor beanRegistInterceptor : interceptors) {
                bd = beanRegistInterceptor.beforeRegist(clz, beanName, scope, dlbf, builder);
                if (bd != null)
                    break;
            }
        }

        if (bd == null)
            bd = builder.getBeanDefinition();

        if (beanInfo != null)
            bd.setAttribute(relativePath, beanInfo.relativePath);
        bd.setScope(scope);

        dlbf.registerBeanDefinition(beanName, bd);

        boolean isUpdate = beanInfo != null ? beanInfo.isUpdate : false;
        String relativePath = beanInfo != null ? beanInfo.relativePath : "";

        BeanDefinitionWrap beanDefinitionWrap = new BeanDefinitionWrap(beanName, bd);

        if (ContextRefresher.class.isAssignableFrom(clz)) {
            ContextHolder.refreshers.register(beanName);
        }

        logRegist(isUpdate ? Info.Updated : Info.Registed, relativePath, beanName, scope);
        return beanDefinitionWrap;
    }

    public static boolean removeBean(DefaultListableBeanFactory dlbf, BeanInfo beanInfo, String beanName) {
        BeanDefinition bd = null;
        if (!Utils.hasLength(beanName))
            if (beanInfo != null)
                beanName = beanInfo.beanName;
        if (!Utils.hasLength(beanName))
            return false;

        try {
            bd = dlbf.getBeanDefinition(beanName);
            if (bd != null) {
                //?bean? relativePath?, ??
                //               BeanRegister.runOnUnregisger(beanName, dlbf);
                String scope = bd.getScope();
                /**
                 * bean?application,singletonbeansession?view? flash?
                 * requestbean,
                 * session,view,flash,requestbeanapplicationbean
                 * application,singletonbean
                 * scopebeanbeanbean
                 */
                if (application_scope.equals(scope))
                    dlbf.destroyScopedBean(beanName);
                else if (singleton_scope.equals(scope))
                    dlbf.destroySingleton(beanName);

                dlbf.removeBeanDefinition(beanName);
                if (beanInfo != null && beanInfo.beanClass != null
                        && PropertyEditor.class.isAssignableFrom(beanInfo.beanClass)) {
                    ContextHolder.refreshers.remover(beanName);
                }

                List<BeanRegistInterceptor> interceptors = ContextHolder.beanRegistIntercpterHolder.getList();
                if (Utils.hasLength(interceptors)) {
                    for (BeanRegistInterceptor beanRegistInterceptor : interceptors) {
                        if (beanRegistInterceptor.afterRemove(beanInfo.beanClass, beanName, scope, dlbf))
                            break;
                    }
                }

                logRegist(Info.Removed, (String) bd.getAttribute(relativePath), beanInfo.beanName, scope);
                return true;
            }
        } catch (NoSuchBeanDefinitionException e) {
            //? BeanDefinition,????beanInfo,
            return true;
        }
        return false;
    }

    public static BeanDefinitionWrap registerBean(ApplicationContext context, DefaultListableBeanFactory dlbf,
            Class<?> clz, Class<?> InterceptorClass, String beanName, String scope, BeanInfo beanInfo) {
        BeanDefinitionBuilder builder = createBuilder(clz, InterceptorClass);
        return registerBean(context, dlbf, builder, clz, beanName, scope, beanInfo);
    }

    public static void refreshContext(ApplicationContext context, Map<Class<?>, ScanedType> refreshedClass) {
        ContextRefresher contextRefresher = null;

        DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) ((AbstractApplicationContext) context)
                .getBeanFactory();

        for (Entry<Class<?>, ScanedType> entry : refreshedClass.entrySet()) {
            if (entry.getValue().getValue() > ScanedType.SAME.getValue()
                    && PropertyEditor.class.isAssignableFrom(entry.getKey())) {
                @SuppressWarnings("unchecked")
                Class<? extends PropertyEditor> propertyEditorType = (Class<? extends PropertyEditor>) entry
                        .getKey();
                PropertyEditorRegister.registerProtertyEditor(dlbf, propertyEditorType);
            }
        }

        List<String> refresherNames = ContextHolder.refreshers.getList();
        if (Utils.hasLength(refresherNames)) {
            for (String contextRefresherName : refresherNames) {
                Object bean = null;
                try {
                    bean = context.getBean(contextRefresherName);
                } catch (BeansException e) {
                    logger.info("bean of [" + contextRefresherName + "] not found!");
                }
                if (bean != null && bean instanceof ContextRefresher) {
                    contextRefresher = (ContextRefresher) bean;
                    contextRefresher.refresh(context, refreshedClass);
                }
            }
        }
    }

}