docs: private static BeanBox doCreateBeanBox(BeanBoxContext ctx, Class<?> clazz) {// NOSONAR
  		BeanBox box = new BeanBox();
  		box.setBeanClass(clazz);
  		box.setSingleton(true);// Annotated class, default is singleton
  
  		if (!ctx.isAllowAnnotation())
  			return box;
  		boolean allowSpringJsrAnno = ctx.allowSpringJsrAnnotation;
  
  		// ========= singleton or prototype
  		if (checkAnnoExist(clazz, PROTOTYPE.class))
  			box.setSingleton(false);
  		else if (allowSpringJsrAnno) {
  			Map<String, Object> m = getAnnoAsMap(clazz, "org.springframework.context.annotation.Scope");
  			if (m != null)
  				for (Entry<String, Object> entry : m.entrySet())
  					if ("value".equals(entry.getKey())) {
  						if ("prototype".equalsIgnoreCase(String.valueOf(entry.getValue())))
  							box.setSingleton(false);
  						else if ("singleton".equalsIgnoreCase(String.valueOf(entry.getValue())))
  							box.setSingleton(true);
  						else
  							BeanBoxException.throwEX("'prototype' or 'singleton' required in @Scope annotation");
  					}
  		}
  
  		// ======== Class inject, if @INJECT, @PARAM put on class
  		Object[] v = getInjectAnnotationAsArray(clazz, allowSpringJsrAnno);
  		if (v != null) {
  			box.setTarget(v[0]);
  			box.setPureValue((Boolean) v[1]);
  			box.setRequired((Boolean) v[2]);
  		}
  
  		// ======== AOP annotated annotations on class
  		Annotation[] annos = clazz.getAnnotations();
  		for (Annotation anno : annos) {
  			if (anno.annotationType().isAnnotationPresent(AOP.class)) {
  				Map<String, Object> annoMap = changeAnnotationValuesToMap(anno);
  				Object aop = annoMap.get("value");
  				String methodNameRule = (String) annoMap.get("method");// name must be method
  				if (methodNameRule != null && methodNameRule.length() > 0 && aop != null)
  					box.addBeanAop(aop, methodNameRule);
  			}
  		}
  
  		// ========== Constructor inject
  		Constructor<?>[] constrs = clazz.getConstructors();
  		for (Constructor<?> constr : constrs) {
  			v = getInjectAnnotationAsArray(constr, allowSpringJsrAnno);
  			if (v != null) {
  				box.setBeanClass(clazz);// anyway set beanClass first
  				if (v[0] != null && EMPTY.class != v[0]) {// 1 parameter only
  					BeanBox inject = new BeanBox();
  					inject.setTarget(v[0]);
  					inject.setPureValue((Boolean) v[1]);
  					inject.setRequired((Boolean) v[2]);
  					inject.setType(constr.getParameterTypes()[0]);
  					box.setConstructor(constr);
  					box.setConstructorParams(new BeanBox[] { inject });
  				} else { // no or many parameter
  					BeanBox[] paramInjects = getParameterInjectAsBeanBoxArray(constr, allowSpringJsrAnno);
  					box.setConstructor(constr);
  					box.setConstructorParams(paramInjects);
  				}
  			}
  		}
  
  		// =================Field inject=================
  		// @INJECT annotations on fields include super class's
  		for (Field f : ReflectionUtils.getSelfAndSuperClassFields(clazz)) {
  			v = getInjectAnnotationAsArray(f, allowSpringJsrAnno);
  			if (v != null) {
  				box.checkOrCreateFieldInjects();
  				BeanBox inject = new BeanBox();
  				inject.setTarget(v[0]);
  				inject.setPureValue((Boolean) v[1]);
  				inject.setRequired((Boolean) v[2]);
  				inject.setType(f.getType());
  				ReflectionUtils.makeAccessible(f);
  				box.getFieldInjects().put(f, inject);
  			}
  		}
  
  		// @INJECT annotations on methods include super class's
  		Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz); 
  		for (Method m : methods) { 
  			// ========== @PostConstruct and @PreDestory
  			if (m.getAnnotation(POSTCONSTRUCT.class) != null || m.getAnnotation(PostConstruct.class) != null) {
  				if (m.getParameterTypes().length > 0)
  					BeanBoxException.throwEX("In jBeanBox, PostConstruct should have no parameter.");
  				ReflectionUtils.makeAccessible(m);
  				box.setPostConstruct(m);
  			}
  			if (m.getAnnotation(PREDESTROY.class) != null || m.getAnnotation(PreDestroy.class) != null) {
  				if (m.getParameterTypes().length > 0)
  					BeanBoxException.throwEX("In jBeanBox, PostConstruct should have no parameter.");
  				ReflectionUtils.makeAccessible(m);
  				box.setPreDestroy(m);
  			}
  
  			// ========== AOP about annotation =========
  			Annotation[] mtdAnnos = m.getAnnotations();
  			for (Annotation anno : mtdAnnos)
  				if (anno.annotationType().isAnnotationPresent(AOP.class)) {
  					Map<String, Object> annoMap = changeAnnotationValuesToMap(anno);
  					Object aop = annoMap.get("value");
  					if (aop != null)
  						box.addMethodAop(aop, m);
  				}
  
  			// =========== method inject annotation ==============
  			v = getInjectAnnotationAsArray(m, allowSpringJsrAnno);
  			if (v != null) {
  				ReflectionUtils.makeAccessible(m);
  				BeanBox oneParam = new BeanBox();
  				oneParam.setTarget(v[0]);
  				oneParam.setPureValue((Boolean) v[1]);
  				oneParam.setRequired((Boolean) v[2]);
  				boolean haveOneParameter = v[0] != null && EMPTY.class != v[0];
  				if (haveOneParameter)
  					oneParam.setType(m.getParameterTypes()[0]); // set parameter type for 1 parameter
  				// @INJECT or @Inject or @Autowired normal method inject
  				box.checkOrCreateMethodInjects();
  				if (haveOneParameter) // 1 parameter only
  					box.getMethodInjects().put(m, new BeanBox[] { oneParam });
  				else { // no or many parameter
  					BeanBox[] paramInjects = getParameterInjectAsBeanBoxArray(m, allowSpringJsrAnno);
  					box.getMethodInjects().put(m, paramInjects);
  				}
  			}
  		}
  		return box;
  
  	}