当前位置:网站首页>2021-03-06 - play with the application of reflection in the framework
2021-03-06 - play with the application of reflection in the framework
2022-07-08 01:17:00 【Mengqi D Xiaowu】
Play with the application of reflection in the framework
Preface : Talking about reflection , You have to mention bytecode , From bytecode to reflection class loading , To apply in the framework , To handwriting IOC and DI The implementation of the
Catalog
2.1 Advantages and disadvantages of reflection
2.2 from JVM Level understanding reflection
2.3 Summarize the reasons for slow reflection performance
3.4 When the class completes initialization
4、 To explore the Class Internal elements
6.1 Application of reflection in framework
6.3 Handwriting Testing Framework
7、Spring Core container class structure
1、 Bytecode
Bytecode files are a series 8 Binary stream of bits and bytes , The data items it contains are composed in a fixed order , And there is no interval between adjacent items .—— Because every structure is strictly standardized , So it can be parsed smoothly .
This use Java Language to describe the structure of byte files . If you don't say much, put the picture first , as follows :
For 16 Base code , Except for the beginning cafe babe, The rest can be roughly translated into : What the hell is this ......
Don't panic, hero , We will learn from what we can know "cafe babe" Let's talk about it . At the beginning of the document 4 Bytes are called magic number , Only with “cafe babe” At the beginning class The file can be accepted by the virtual machine , this 4 One byte is the identification of bytecode file . Shift your eyes to the right ,0000 It's a compiler jdk The minor version number of the version 0,0034 Convert to decimal yes 52, It's the main version number ,java The version number of is from 45 Start , except 1.0 and 1.1 Is to use 45.x Outside , Every large version in the future , Version number plus one . in other words , Compile and generate the class Of documents jdk Version is 1.8.0. adopt java -version The command is slightly verified , But it turns out .
Java(TM) SE Runtime Environment (build 1.8.0_131-b11) Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
The result is verified .
Continuing down is the constant pool .
Constant pool capacity meter value (constant_pool_count), What is special is , And java Different habits , This capacity count is from 1 instead of 0 Start , For other sets , Include interface index set 、 Field table set 、 The capacity count of method table set is the same as the general habit , It's from 0 At the beginning .
……
...... Bytecode is not the focus of this article , Interested students can learn more about ......
2、 Reflection
In layman's terms , utilize JDK Reflections provided API Make a reflection call .
Reflection is more flexible than the ordinary way of creating instances —— Good scalability .
Through comparison, we found that , Reflection takes longer . Performance analysis of reflection mechanism :
@sun.reflect.CallerSensitive
public static native java.lang.Class<?> getCallerClass();
@CallerSensitive
public static Class<?> forName(String className)
throws ClassNotFoundException {
// call native Method to get the caller's Class
Class<?> caller = Reflection.getCallerClass();
// call native Methods according to the className Find bytecode object , And load it 、 analysis
return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}
/** Called after security check for system loader access checks have been made. */
private static native Class<?> forName0(String name, boolean initialize,
ClassLoader loader,
Class<?> caller)
throws ClassNotFoundException;
@CallerSensitive
public T newInstance()
throws InstantiationException, IllegalAccessException
{
// When instantiating through reflection , If you have configuration SecurityManager Safety verification is required first , Ordinary instantiation does not require
if (System.getSecurityManager() != null) {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
}
// NOTE: the following code may not be strictly correct under
// the current Java memory model.
// Constructor lookup
if (cachedConstructor == null) {
if (this == Class.class) {
throw new IllegalAccessException(
"Can not call newInstance() on the Class for java.lang.Class"
);
}
try {
Class<?>[] empty = {};
final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
// Disable accessibility checks on the constructor
// since we have to do the security check here anyway
// (the stack depth is wrong for the Constructor's
// security check to work)
// Safety verification for the first time
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
c.setAccessible(true);
return null;
}
});
// Cache the constructor , Improve performance the next time you create an object through reflection
cachedConstructor = c;
} catch (NoSuchMethodException e) {
throw (InstantiationException)
new InstantiationException(getName()).initCause(e);
}
}
Constructor<T> tmpConstructor = cachedConstructor;
// Security check (same as in java.lang.reflect.Constructor)
// The second safety verification , This modifier stay JDK Inside is a int Value to represent the ,
int modifiers = tmpConstructor.getModifiers();
if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
if (newInstanceCallerCache != caller) {
Reflection.ensureMemberAccess(caller, this, null, modifiers);
newInstanceCallerCache = caller;
}
}
// Run constructor
try {
// Instantiate objects through constructors
return tmpConstructor.newInstance((Object[])null);
} catch (InvocationTargetException e) {
Unsafe.getUnsafe().throwException(e.getTargetException());
// Not reached
return null;
}
}
2.1 Advantages and disadvantages of reflection
advantage
- Increase the flexibility of the program , Avoid writing down inherent logic
- The code is concise , High readability , Increase code reuse rate
shortcoming
- Compared with direct call , In the case of a large number of visits , Reflection will lead to a significant decline in system performance
- Breaking the encapsulation of classes , There is a certain security risk
2.2 from JVM Level understanding reflection
JVM adopt Class Find the class name of Class Bytecode file , And then through ClassLoader The class loading mechanism of allocates objects in heap memory ( Don't consider that the object is on the stack ,TLAB Distribution on ).
2.3 Summarize the reasons for slow reflection performance
- Reflection calls will perform a series of security checks
- Reflection requires calling a series of nativenative Method to implement
- seek ClassClass Bytecode process , Such as through CClassNamelassName Find the corresponding bytecode, find the corresponding bytecode CClasslass, Then load 、 analysis , This will also be slower , And this will be slower , and new There is no need to look for , Because the symbolic reference has been converted to direct reference in the parsing phase of the connection
- Input verification
3、 Class loading process
Class loading trilogy , load 、 Connect 、 initialization
3.1 load
- • load .class file , There are mainly the following ways :
- • Load from the local file system
- • Download... Over the Internet
- • from zip.jar Package to load .class file
- • Load from the storage middleware ( database 、 cache …)
- • stay JVM Dynamic bytecode recombination during operation (ASM)
3.2 Connect
- Connection is to merge the binary data of the class that has been read into memory into JVM In the runtime environment of , There are three main stages in the connection process
- • Class validation , Check the class file ( Version number 、 modulus ) In order to make sure .class accord with JVM standard
- • Class preparation , Allocate constant pool space , Parsing constant pool , Allocation of static variables , But it will not initialize , Only default values will be given
- • Class parsing , Parse parent class , Parsing interface , analysis Filed, List of parsing methods ( Include stack 、 Byte code table 、 Anomaly table 、 Local variable table 、 Run pointer ), Convert binary like symbolic references into direct references
3.3 initialization
- JVM Execute the initial statement of the class , Assign a value to the static variable of the class
- • If the class has not been loaded and connected yet , Then load and connect first
- • If this class has a parent , And the parent class has no initial words , Then initialize the parent class first
- • If there is an initialization statement in the class (Static block ), Execute initialization statements in turn
3.4 When the class completes initialization
- • Create an instance of a class new xxxClass() || Class.newInstance() || constructor.newInstance()
- • Accessing a static variable of a , Or assign values to static variables
- • Calling static methods of a class
- •Class.forName(" Package class name "), because forName There's one in it init Parameter is true
- • Complete the initialization of subclasses , It will also complete the initialization of this class ( Except for the interface )
- • This class is the program boot entry (main entrance perhaps test entrance )
3.5 Class How to get objects
- •Class clazz = xxxClass.class;// Initialization process is not completed
- •Class class = instanceObj.getClass;// Object generated , Complete the initialization process
- •Class clazz = xxxClassLoader.loadClass(" Package class name ");// Initialization process not completed
- •Class clazz = Class.forName(" Package class name ");// Complete the initialization process
4、 To explore the Class Internal elements
Class clazz = Class.forName(XXXX);
clazz.newInstance();
clazz.newInstance(); What is the essence ?
The essence :JDK→constructor
JVM→instanceKlass→instanceOop OopDesc→Object(Java)
5、 The singleton pattern
• Privatization constructor
• Globally unique public access point
The singleton mode can be broken through the reflection mechanism . The singleton pattern , Please move to another article in design patterns : Single case mode in JDK as well as Spring How to concatenate in the source code
6、Spring IOC and DI
IOC There are three ways to create :
- How it was created 1: Empty parameter construction creation
- How it was created 2: Static factory creation
- How it was created 3: Instance factory creation
DI There are three ways to create :
- How it was created 1: Parametric construction creates
- How it was created 2:setter establish
- How it was created 3:field establish (very few usage)
6.1 Application of reflection in framework
stay Sping Medium IOC Instance creation
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
// Instantiation Bean Methods
return instantiateBean(beanName, mbd);
}
/**
* Instantiate the given bean using its default constructor.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @return a BeanWrapper for the new instance
*/
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
public T newInstance(Object ... initargs)
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, null, modifiers);
}
}
if ((clazz.getModifiers() & Modifier.ENUM) != 0)
throw new IllegalArgumentException("Cannot reflectively create enum objects");
ConstructorAccessor ca = constructorAccessor; // read volatile
if (ca == null) {
ca = acquireConstructorAccessor();
}
@SuppressWarnings("unchecked")
T inst = (T) ca.newInstance(initargs);
return inst;
}
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
return (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
}
catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
}
catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
}
}
analysis Bean Of class spring Is used through classLoader The way
@Nullable
private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
throws ClassNotFoundException {
ClassLoader beanClassLoader = getBeanClassLoader();
ClassLoader dynamicLoader = beanClassLoader;
boolean freshResolve = false;
if (!ObjectUtils.isEmpty(typesToMatch)) {
// When just doing type checks (i.e. not creating an actual instance yet),
// use the specified temporary class loader (e.g. in a weaving scenario).
ClassLoader tempClassLoader = getTempClassLoader();
if (tempClassLoader != null) {
dynamicLoader = tempClassLoader;
freshResolve = true;
if (tempClassLoader instanceof DecoratingClassLoader) {
DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
for (Class<?> typeToMatch : typesToMatch) {
dcl.excludeClass(typeToMatch.getName());
}
}
}
}
String className = mbd.getBeanClassName();
if (className != null) {
Object evaluated = evaluateBeanDefinitionString(className, mbd);
if (!className.equals(evaluated)) {
// A dynamically resolved expression, supported as of 4.2...
if (evaluated instanceof Class) {
return (Class<?>) evaluated;
}
else if (evaluated instanceof String) {
className = (String) evaluated;
freshResolve = true;
}
else {
throw new IllegalStateException("Invalid class name expression result: " + evaluated);
}
}
if (freshResolve) {
// When resolving against a temporary class loader, exit early in order
// to avoid storing the resolved Class in the bean definition.
if (dynamicLoader != null) {
try {
return dynamicLoader.loadClass(className);
}
catch (ClassNotFoundException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
}
}
}
return ClassUtils.forName(className, dynamicLoader);
}
}
// Resolve regularly, caching the result in the BeanDefinition...
return mbd.resolveBeanClass(beanClassLoader);
}
Set instance properties
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
// Inject... By name
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
// Inject... According to type
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// adopt @Resource @Autowre Of BeanPostProcessor
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
/**
* Either this or {@link #getResourceToInject} needs to be overridden.
*/
// Injecting attributes through reflection
protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
throws Throwable {
if (this.isField) {
Field field = (Field) this.member;
ReflectionUtils.makeAccessible(field);
field.set(target, getResourceToInject(target, requestingBeanName));
}
else {
if (checkPropertySkipping(pvs)) {
return;
}
try {
Method method = (Method) this.member;
ReflectionUtils.makeAccessible(method);
method.invoke(target, getResourceToInject(target, requestingBeanName));
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
6.2 Handwriting Spring IOC、DI
Dynamically create object instances
Methods for dynamically manipulating instance objects 、 attribute
1. First create IOC、DI class
public class A {
public A() {
System.out.println("A whitout parameters Constructor invoke!");
}
public static B createBObj() { //factory-method
System.out.println("A static function createBObj() invoke!");
return new B();
}
public C createCObj() { //instance-method
System.out.println("a's createCObj() invoke!");
return new C();
}
}
public class B {
}
public class C {
}
public class D {
private A a;
private B b;
public D() {
System.out.println("D without parameters Constructor invoke!");
}
public D(A a, B b) {
System.out.println("D constructor with parameters invoke!");
this.a = a;
this.b = b;
}
}
public class E {
private A a;
private B b;
public void setA(A a) {
System.out.println("E setA() invoke!");
this.a = a;
}
public void setB(B b) {
System.out.println("E setB() invoke!");
this.b = b;
}
}
2.BeanConfig
public class BeanConfig { //spring-ioc.xml spring-di.xml
private String id;
private String clazz;
private String factoryMethod;
private String factoryBean;
private HashMap dependencyHashMap = new HashMap<String, List<String>>();
private List<String> constructBeans = new ArrayList<>();
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClazz() {
return clazz;
}
public void setClazz(String clazz) {
this.clazz = clazz;
}
public String getFactoryMethod() {
return factoryMethod;
}
public void setFactoryMethod(String factoryMethod) {
this.factoryMethod = factoryMethod;
}
public String getFactoryBean() {
return factoryBean;
}
public void setFactoryBean(String factoryBean) {
this.factoryBean = factoryBean;
}
public void addConstructBeanId(String beanId){
constructBeans.add(beanId);
}
public List<String> getConstructBeans() {
return constructBeans;
}
public void putDependcyBeanId(String propName,String beanId){
dependencyHashMap.put(propName,beanId);
}
public HashMap<String, String> getDependencyHashMap(){
return dependencyHashMap;
}
}
3.BootStrap
public class BootStrap {
public static void main(String[] args) throws Exception {
// Simulation analysis xml Get beanConfigs
List<BeanConfig> beanConfigs = parseXmltoBeanConfig();
// loop
for (BeanConfig tmpconfig : beanConfigs) {
if (null != tmpconfig.getClazz()) {
// Get clazz
Class clazz = Class.forName(tmpconfig.getClazz());
if (null != tmpconfig.getFactoryMethod())
{
// be based on Class Object acquisition method object
Method method = clazz.getDeclaredMethod(tmpconfig.getFactoryMethod());
IOCContainer.putBean(tmpconfig.getId(), method.invoke(null));
} else {
// hold the bean reference
// Parameter construction
if(tmpconfig.getConstructBeans().size()>0) {
List<String> contructBeanIds = tmpconfig.getConstructBeans();
Object[] constructorParams = new Object[contructBeanIds.size()];
Class[] contructorClasses = new Class[contructBeanIds.size()];
for (int i = 0; i < contructBeanIds.size(); i++) {
Object parami = IOCContainer.getBean(contructBeanIds.get(i));
if (parami == null) {
System.out.println("init error,");
throw new Exception("init-err");
}
constructorParams[i] = parami;
contructorClasses[i] = parami.getClass();
}
Constructor c = clazz.getConstructor(contructorClasses);// Get the structure with parameters
IOCContainer.putBean(tmpconfig.getId(), c.newInstance(constructorParams));
}else {
IOCContainer.putBean(tmpconfig.getId(), clazz.newInstance());
}
//DI
if(tmpconfig.getDependencyHashMap().size()>0){
for(Map.Entry<String,String> entry : tmpconfig.getDependencyHashMap().entrySet()){
Object bean = IOCContainer.getBean(tmpconfig.getId());
String methodKey = entry.getKey();
String beanId = entry.getValue();
Object[] params = new Object[1];
params[0] = IOCContainer.getBean(beanId);
Class[] paramTypes = new Class[1];
paramTypes[0] = params[0].getClass();
String methodName
= "set"
+ methodKey.substring(0,1).toUpperCase()
+ (methodKey.length()>1?methodKey.substring(1,methodKey.length()-1):"");
Method setx = bean.getClass().getMethod(methodName,paramTypes);
setx.invoke(bean,params);
}
}
}
} else if(null != tmpconfig.getFactoryBean()) {
// Get the entity from the container bean
Object obj = IOCContainer.getBean( tmpconfig.getFactoryBean());
Method method = obj.getClass().getDeclaredMethod(tmpconfig.getFactoryMethod());
IOCContainer.putBean(tmpconfig.getId(), method.invoke(obj));
}else{
System.out.println("Configuration is required!");
}
}
//IOC test
A a = IOCContainer.getBean("a",A.class);
B b = IOCContainer.getBean("b",B.class);
C c = IOCContainer.getBean("c",C.class);
D d = IOCContainer.getBean("d",D.class);
E e = IOCContainer.getBean("e", E.class);
}
public void doDependencyInjection(){
// IOCContainer get Object
// Reflection get Method
// Resolve the relationship of dependency injection DependencyHashMap
// Reflection call 3 Kind of Object Constructor, setter Method to set the dependencies between objects field(very few usage)
}
/**
* Simulate an analysis XML The process
*
* @return
*/
private static List<BeanConfig> parseXmltoBeanConfig() {
//TODO
List<BeanConfig> beanConfigs = new ArrayList<BeanConfig>();
BeanConfig beanConfig1 = new BeanConfig();
beanConfig1.setClazz("com.iocdi.A");
beanConfig1.setId("a");
beanConfigs.add(beanConfig1);
BeanConfig beanConfig2 = new BeanConfig();
beanConfig2.setClazz("com.iocdi.A");
beanConfig2.setId("b");
beanConfig2.setFactoryMethod("createBObj");
beanConfigs.add(beanConfig2);
BeanConfig beanConfig3 = new BeanConfig();
beanConfig3.setId("c");
beanConfig3.setFactoryBean("a");
beanConfig3.setFactoryMethod("createCObj");
beanConfigs.add(beanConfig3);
BeanConfig beanConfig4 = new BeanConfig();
beanConfig4.setId("d");
beanConfig4.setClazz("com.iocdi.D");
beanConfig4.addConstructBeanId("a");
beanConfig4.addConstructBeanId("b");
beanConfigs.add(beanConfig4);
BeanConfig beanConfig5 = new BeanConfig();
beanConfig5.setId("e");
beanConfig5.setClazz("com.iocdi.E");
beanConfig5.putDependcyBeanId("a","a");
beanConfig5.putDependcyBeanId("b","b");
beanConfigs.add(beanConfig5);
return beanConfigs;
}
}
4.IOCContainer
public class IOCContainer {
private static HashMap IoContainer = new HashMap();
public static void putBean(String id,Object object){
IoContainer.put(id,object);
}
public static Object getBean(String id){
return IoContainer.get(id);
}
public static <T> T getBean(String id,Class<T> clazz){
return (T)IoContainer.get(id);
}
}
6.3 Handwriting Testing Framework
1. annotation Test
/**
* Indicates that the annotated method is a test method.
* This annotation should be used only on parameterless static methods.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE, ElementType.FIELD})
public @interface Test {
// method
// normal
// single element
}
2.OrderTestCase
//@Test
public class OrderTestCase {
@Test
public static void m1() {System.out.println("m1 is ok."); }
public static void m2() { }
@Test
public static void m3() {
throw new RuntimeException("Boom");
}
public static void m4() { }
@Test
public static void m5() { System.out.println("m5 is ok."); }
public static void m6() { }
@Test
public static void m7() {
throw new RuntimeException("Crash");
}
public static void m8() { }
}
3.MainTest
public class MainTest {
public static void main(String[] args) {
int passed=0, failed=0;
try{
// hard code to get TestCase Classes
//TODO scan package to get all of TestCase Classes
Method[] methods = Class.forName(args[0]).getMethods(); // how many methods?
for(Method m : methods){
if (m.isAnnotationPresent(Test.class)){
try{
m.invoke(null);
passed++;
}catch (Throwable ex){
System.out.printf("Test %s failed: %s %n", m, ex.getCause());
failed++;
}
}
}
}catch (ClassNotFoundException ex){
ex.printStackTrace();
}
System.out.printf("Passed: %d, Failed %d%n", passed, failed);
}
}
7、Spring Core container class structure
7.1 BeanFactory
Spring Bean The creation of is a typical factory model , This series of Bean factory , That is to say IOC Container provides a lot of convenience and basic services for developers to manage the dependency relationship between objects , stay Spring There are many of them IOC The implementation of container is for users to choose and use , The relationship between them is as follows :
among
BeanFactory As an interface class at the top level , It defines the IOC Basic functional specification of the container , BeanFactory There are three subcategories : ListableBeanFactory 、 Hierarc hicalBeanFactory and AutowireCapableBeanFactory .
But from the above figure, we can find that the final default implementation class is DefaultListableBeanFactory , He implements all the interfaces . Then why define so many levels of interfaces ? Check the source code and description of these interfaces and find , Each interface has its own occasion , It is mainly to distinguish between Spring In the process of internal operation, the transfer and transformation of objects , Restrictions on data access to objects . for example ListableBeanFactory Interfaces represent these Bean It is listable , and HierarchicalBeanFactory It means these Bean It's a matter of inheritance , That is, every one of them Bean There may be a father Bean .AutowireCapableBeanFactory Interface definition Bean Automatic assembly rules . These four interfaces define Bean Set 、 Bean The relationship between 、 as well as Bean Behavior is the most basic IOC Container interface BeanFactory
public interface BeanFactory {
// Yes FactoryBean Definition of escape , Because if you use bean Name search for FactoryBean The resulting object is a factory generated object ,
// If you need to get the factory itself , Need to escape
String FACTORY_BEAN_PREFIX = "&";
// according to bean Name , To get in IOC Get... In the container bean example
Object getBean(String name) throws BeansException;
// according to bean And Class Type to get bean example , Added type security verification mechanism .
<T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
// Provide right bean Search for , See if it's in IOC The container has the name bean
boolean containsBean(String name);
// according to bean The name gets bean example , And judge this at the same time bean Is it a single case
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
// obtain bean Example of Class type
@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
// obtain bean Another name for , If you search by alias , Then its original name will also be retrieved
String[] getAliases(String name); }
stay BeanFactory It's only for IOC The basic behavior of the container is defined , I don't care about you at all Bean How to define how to load . Just as we only care about what we get in the factory , As for how the factory produces these objects , This basic interface doesn't care .
And you need to know how the factory generates objects , We need to look at specific IOC Container implementation , Spring Offers many IOC Implementation of container . such as XmlBeanFactoryClasspathXmlApplicationContext etc. . among XmlBeanFactory It is aimed at the most basic IOC Implementation of container , This IOC The container can read XML File defined BeanDefinition XML In the document bean Description of ) if XmlBeanFactory It's the cock in the container , ApplicationContext It should be counted as Gao Shuaifu in the container .
ApplicationContext yes Spring An advanced IOC Containers , In addition to providing IOC In addition to the basic functions of the container , The following additional services are also provided for users .
from ApplicationContext Interface implementation , We can see its characteristics :
1. Supporting information sources , Internationalization can be achieved .( Realization MessageSource Interface )
2. Access resources . Realization ResourcePatternResolver Interface , Later chapters will talk about
3. Support application events . Realization ApplicationEventPublisher Interface
7.2 BeanDefinition
SpringIOC Containers manage all kinds of things that we define Bean Objects and their relationships , Bean The object is Spring The realization is based on BeanDef inition To describe the , Under its inheritance system :
Bean The process of parsing is very complicated , The functions are divided in detail , Because there are a lot of things that need to be expanded here , There has to be enough flexibility , In response to possible changes . Bean The main purpose of the analysis is to Spring Profile resolution . This parsing process is mainly completed by the class in the figure below :
边栏推荐
- Arm bare metal
- Chapter IV decision tree
- The communication clock (electronic time-frequency or electronic time-frequency auxiliary device) writes something casually
- [note] common combined filter circuit
- 2.非线性回归
- New library online | cnopendata China Star Hotel data
- For the first time in China, three Tsinghua Yaoban undergraduates won the stoc best student thesis award
- Saving and reading of network model
- String usage in C #
- 11. Recurrent neural network RNN
猜你喜欢
The combination of relay and led small night light realizes the control of small night light cycle on and off
[note] common combined filter circuit
130. 被圍繞的區域
Cs5212an design display to VGA HD adapter products | display to VGA Hd 1080p adapter products
Markdown learning (entry level)
Get started quickly using the local testing tool postman
2022-07-07: the original array is a monotonic array with numbers greater than 0 and less than or equal to K. there may be equal numbers in it, and the overall trend is increasing. However, the number
AI遮天传 ML-回归分析入门
133. 克隆图
8.优化器
随机推荐
USB type-C mobile phone projection scheme | USB type-C docking station scheme | TV / projector type-C converter scheme | ag9300ag9310ag9320
Chapter improvement of clock -- multi-purpose signal modulation generation system based on ambient optical signal detection and custom signal rules
7.正则化应用
The combination of relay and led small night light realizes the control of small night light cycle on and off
Four digit nixie tube display multi digit timing
2. Nonlinear regression
网络模型的保存与读取
Image data preprocessing
EDP to LVDS conversion design circuit | EDP to LVDS adapter board circuit | capstone/cs5211 chip circuit schematic reference
5、离散控制与连续控制
Codeforces Round #804 (Div. 2)
NVIDIA Jetson test installation yolox process record
基础篇——整合第三方技术
Basic implementation of pie chart
swift获取url参数
The communication clock (electronic time-frequency or electronic time-frequency auxiliary device) writes something casually
Get started quickly using the local testing tool postman
Ag7120 and ag7220 explain the driving scheme of HDMI signal extension amplifier | ag7120 and ag7220 design HDMI signal extension amplifier circuit reference
Cs5212an design display to VGA HD adapter products | display to VGA Hd 1080p adapter products
AI zhetianchuan ml novice decision tree