文章目录 1.目录 2.SmartAnimal.java 接口(JDK代理必须有接口) 3.SmartDog.java 4.SmartAnimalAspect.java 5.SunSpringApplicationContext.java 1.在Bean的后置处理器之后使用动态代理 2.完整代码 6.测试 1.AppMain.java 调用被代理的类的方法 2.结果 7.Spring底层机制总结 1.扫描包,存储Bean定义信息,初始化单例池,依赖注入 2.后置处理器的Before方法对Bean进行处理 3.实现InitializingBean接口或者有@PostConstruct注解的初始化方法被调用 4.后置处理器的After方法对Bean进行处理 5.如果发现某个类被AOP了,则在后置处理器之后就会返回代理对象,当目标对象使用代理对象调用方法时,就可以得到目标对象和调用的方法的信息
1.目录
2.SmartAnimal.java 接口(JDK代理必须有接口)
package com. sunxiansheng. sunspring. compent ;
public interface SmartAnimal { public float getSum ( float a, float b) ; public float getSub ( float a, float b) ; }
3.SmartDog.java
package com. sunxiansheng. sunspring. compent ; import com. sunxiansheng. sunspring. annotation. Component ;
import org. slf4j. Logger ;
import org. slf4j. LoggerFactory ;
@Component
public class SmartDog implements SmartAnimal { private static final Logger log = LoggerFactory . getLogger ( SmartDog . class ) ; @Override public float getSum ( float a, float b) { log. info ( "SmartDog...getSum...res=" + ( a + b) ) ; return a + b; } @Override public float getSub ( float a, float b) { log. info ( "SmartDog...getSub...res=" + ( a - b) ) ; return a - b; } }
4.SmartAnimalAspect.java
package com. sunxiansheng. sunspring. compent ; import org. slf4j. Logger ;
import org. slf4j. LoggerFactory ;
public class SmartAnimalAspect { private static final Logger log = LoggerFactory . getLogger ( SmartAnimalAspect . class ) ; public static void showBeginLog ( ) { log. info ( "AOP:前置通知-方法执行开始" ) ; } public static void showEndLog ( ) { log. info ( "AOP:后置通知-方法执行结束" ) ; } }
5.SunSpringApplicationContext.java
1.在Bean的后置处理器之后使用动态代理
2.完整代码
package com. sunxiansheng. sunspring. ioc ; import com. sunxiansheng. sunspring. annotation. * ;
import com. sunxiansheng. sunspring. annotation. myenum. MyScope ;
import com. sunxiansheng. sunspring. compent. SmartAnimalAspect ;
import com. sunxiansheng. sunspring. processor. BeanPostProcessor ;
import com. sunxiansheng. sunspring. processor. InitializingBean ;
import org. slf4j. Logger ;
import org. slf4j. LoggerFactory ; import java. io. File ;
import java. lang. reflect. Field ;
import java. lang. reflect. InvocationTargetException ;
import java. lang. reflect. Proxy ;
import java. net. URL ;
import java. util. ArrayList ;
import java. util. List ;
import java. util. concurrent. ConcurrentHashMap ;
public class SunSpringApplicationContext { private static final Logger log = LoggerFactory . getLogger ( SunSpringApplicationContext . class ) ; private ConcurrentHashMap < String , BeanDefintion > beanDefintionMap = new ConcurrentHashMap < > ( ) ; private ConcurrentHashMap < String , Object > singletonObjects = new ConcurrentHashMap < > ( ) ; private List < BeanPostProcessor > beanPostProcessorList = new ArrayList < > ( ) ; public SunSpringApplicationContext ( Class < ? > configClass) throws ClassNotFoundException , InstantiationException , IllegalAccessException { beanDefinitionByScan ( configClass) ; initSingletonObjects ( ) ; } private void populateBeans ( Object bean) { Class < ? > clazz = bean. getClass ( ) ; Field [ ] fields = clazz. getDeclaredFields ( ) ; for ( Field field : fields) { if ( field. isAnnotationPresent ( Resource . class ) ) { String fieldName = field. getName ( ) ; Object beanObject = null ; BeanDefintion beanDefintion = beanDefintionMap. get ( fieldName) ; try { beanObject = getBean ( fieldName) ; } catch ( Exception e) { throw new RuntimeException ( e) ; } field. setAccessible ( true ) ; try { field. set ( bean, beanObject) ; log. info ( "依赖注入成功:{} => {}.{}" , beanObject. getClass ( ) , clazz, fieldName) ; } catch ( IllegalAccessException e) { e. printStackTrace ( ) ; } } } } private void initSingletonObjects ( ) { beanDefintionMap. forEach ( ( beanName, beanDefintion) -> { try { Object bean = createBean ( beanDefintion) ; if ( bean != null ) { singletonObjects. put ( beanName, bean) ; } } catch ( Exception e) { e. printStackTrace ( ) ; } } ) ; log. info ( "根据bean定义信息初始化单例池:{}" , singletonObjects) ; } public Object getBean ( String name) throws Exception { BeanDefintion beanDefintion = beanDefintionMap. get ( name) ; if ( beanDefintion == null ) { throw new NullPointerException ( "在bean定义中没有找到bean对象" ) ; } MyScope scope = beanDefintion. getScope ( ) ; Object bean = null ; if ( scope == MyScope . SINGLETON ) { bean = singletonObjects. get ( name) ; } else { bean = createProtoTypeBean ( beanDefintion) ; } populateBeans ( bean) ; Object current = bean; for ( BeanPostProcessor beanPostProcessor : beanPostProcessorList) { Object bean1 = beanPostProcessor. postProcessBeforeInitialization ( bean, name) ; if ( bean1 != null ) { current = bean1; } } init ( current) ; for ( BeanPostProcessor beanPostProcessor : beanPostProcessorList) { bean = beanPostProcessor. postProcessAfterInitialization ( current, name) ; if ( bean == null ) { bean = current; } } if ( name. equals ( "smartDog" ) ) { final Object proxyObject = current; bean = Proxy . newProxyInstance ( current. getClass ( ) . getClassLoader ( ) , current. getClass ( ) . getInterfaces ( ) , ( proxy, method, args) -> { SmartAnimalAspect . showBeginLog ( ) ; Object invoke = method. invoke ( proxyObject, args) ; SmartAnimalAspect . showEndLog ( ) ; return invoke; } ) ; log. info ( "SmartDog返回代理对象:{}" , bean. getClass ( ) ) ; return bean; } log. info ( "getBean:{}" , bean. getClass ( ) ) ; return bean; } public void init ( Object bean) { if ( bean instanceof InitializingBean ) { ( ( InitializingBean ) bean) . afterPropertiesSet ( ) ; } } private Object createBean ( BeanDefintion beanDefintion) throws Exception { Class < ? > clazz = beanDefintion. getClazz ( ) ; if ( beanDefintion. getScope ( ) == MyScope . PROTOTYPE ) { return null ; } Object bean = clazz. getDeclaredConstructor ( ) . newInstance ( ) ; return bean; } private static Object createProtoTypeBean ( BeanDefintion beanDefintion) throws InstantiationException , IllegalAccessException , InvocationTargetException , NoSuchMethodException { Class < ? > clazz = beanDefintion. getClazz ( ) ; Object bean = clazz. getDeclaredConstructor ( ) . newInstance ( ) ; return bean; } private void beanDefinitionByScan ( Class < ? > configClass) { ComponentScan componentScan = configClass. getDeclaredAnnotation ( ComponentScan . class ) ; String path = componentScan. packagePath ( ) ; log. info ( "扫描的包路径:{}" , path) ; ClassLoader classLoader = SunSpringApplicationContext . class . getClassLoader ( ) ; path = path. replace ( "." , "/" ) ; URL resource = classLoader. getResource ( path) ; File file = new File ( resource. getFile ( ) ) ; if ( file. isDirectory ( ) ) { File [ ] files = file. listFiles ( ) ; for ( File f : files) { String absolutePath = f. getAbsolutePath ( ) ; if ( absolutePath. endsWith ( ".class" ) ) { String className = extractClassName ( absolutePath) ; String fullPath = path. replace ( "/" , "." ) + "." + className; Class < ? > aClass = null ; try { aClass = classLoader. loadClass ( fullPath) ; } catch ( ClassNotFoundException e) { throw new RuntimeException ( e) ; } if ( aClass. isAnnotationPresent ( Component . class ) ) { log. info ( "扫描到Spring Bean:{}" , aClass) ; if ( BeanPostProcessor . class . isAssignableFrom ( aClass) ) { Object o = null ; try { o = aClass. getDeclaredConstructor ( ) . newInstance ( ) ; } catch ( Exception e) { log. info ( "BeanPostProcessor实例化失败:{}" , e) ; } if ( o instanceof BeanPostProcessor ) { beanPostProcessorList. add ( ( BeanPostProcessor ) o) ; } log. info ( "BeanPostProcessor实例化成功:{}" , o) ; continue ; } BeanDefintion beanDefintion = new BeanDefintion ( ) ; if ( aClass. isAnnotationPresent ( Scope . class ) ) { Scope scope = aClass. getDeclaredAnnotation ( Scope . class ) ; MyScope value = scope. value ( ) ; beanDefintion. setScope ( value) ; } else { beanDefintion. setScope ( MyScope . SINGLETON ) ; } beanDefintion. setClazz ( aClass) ; Component component = aClass. getDeclaredAnnotation ( Component . class ) ; String beanName = component. value ( ) ; if ( "" . equals ( beanName) ) { beanName = className. substring ( 0 , 1 ) . toLowerCase ( ) + className. substring ( 1 ) ; } beanDefintionMap. put ( beanName, beanDefintion) ; } else { log. info ( "这不是一个Spring Bean={}" , aClass) ; } } } } log. info ( "将bean定义信息放到beanDefintionMap:{}" , beanDefintionMap) ; } private String extractClassName ( String filePath) { int lastSlashIndex = filePath. lastIndexOf ( '/' ) ; int lastDotIndex = filePath. lastIndexOf ( '.' ) ; return filePath. substring ( lastSlashIndex + 1 , lastDotIndex) ; } }
6.测试
1.AppMain.java 调用被代理的类的方法
2.结果
7.Spring底层机制总结
1.扫描包,存储Bean定义信息,初始化单例池,依赖注入
2.后置处理器的Before方法对Bean进行处理
3.实现InitializingBean接口或者有@PostConstruct注解的初始化方法被调用
4.后置处理器的After方法对Bean进行处理
5.如果发现某个类被AOP了,则在后置处理器之后就会返回代理对象,当目标对象使用代理对象调用方法时,就可以得到目标对象和调用的方法的信息