静态内部类与非静态内部类的区别?
文章首发于:clawhub.club
重要:非静态内部类持有外部类的引用。
是否拥有静态成员(属性,方法):
非静态内部类不可以有静态成员,静态内部类可以。
访问外部类的成员区别
静态内部类只能直接访问外部类的静态成员,而非静态内部类可以访问外部类的所有成员。
类的声明区别
静态内部类的声明不依赖外部类,而非静态内部类需要先有外部类,之后才能new。
12345# 静态内部类OutClass.InnerClass innerClass = new OutClass.InnerClass(); # 非静态内部类OutClass.InnerClass innerClass = new OutClass().new InnerClass();
依赖倒置、控制反转、依赖注入之间的关系
文章首发于:clawhub.club
简单介绍
依赖倒置:Dependency Inversion Principle(DIP) 依赖倒置原则,高层模块不应该依赖于低层模块。两者都应该依赖于抽象。抽象不应该取决于细节。细节应该取决于抽象。
控制反转:Inversion of Control(IoC)控制反转,是面向对象编程的一种原则,用来降低代码之间的耦合度,由外部的容器提供组件,由主动获取变为被动。
依赖注入:Dependency Injection(DI)依赖注入,将依赖实例注入到高层模块,是实现IoC的一种方式。
关系梳理依赖倒置是设计原则可以降低模块之间的耦合。IoC是设计模式,可以遵守依赖倒置原则。DI是实现IoC的一种方式,还有其他的方式,比如:依赖查找等。
参考资料轻松学,浅析依赖倒置(DIP)、控制反转(IOC)和依赖注入(DI)浅谈面向对象五大原则 S.O.L.I.D
Spring-AOP【十】简单小结
总结简单的对Spring-AOP源码分析做个小结。
我是通过一个小栗子开启的这个系列,首先建一个用于增强功能的bean,之后定义切面(包括切点和多个通知),再通过aop:aspectj-autoproxy/标签开启自动代理,最后通过ClassPathXmlApplicationContext读取配置文件,测试成果。
因为使用了ClassPathXmlApplicationContext,所以在构造的时候就实例化完成了单例实例,当然那个用于增强功能的bean也被增强了,确切地说返回给IOC容器中的已经是增强了功能的代理实例。
增强入口就在AbstractAutoProxyCreator的 postProcessAfterInitialization(@Nullable Object bean, String beanName)方法。简单点描述流程就是为特定的bean获取其适合的增强器,之后创建代理对象对象并返回。
虽然流程看起来很简单,但是里面的实现确实特别的复杂,各种反射,动态代理,CGLIB,还有AspectJ表达式解析…
简单分析完AOP,愈发知道自己的不足了。再接再厉!
Spring-AOP【九】创建代理对象
引言至此,Spring-AOP的核心逻辑已经走了一半了,获取了目标类所适应的增强器列表,下面开始分析获取代理的过程。回到初始代码入口:AbstractAutoProxyCreator的postProcessAfterInitialization(@Nullable Object bean, String beanName)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 /** * 如果bean被子类标识为一个代理,则使用已配置的拦截器创建一个代理。 * * @see #getAdvicesAndAdvisorsForBean */ @Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != ...
Spring-AOP【八】AopUtils的findAdvisorsThatCanApply方法分析
引言这篇文章主要分析对于指定的类,获取它的合适的增强器,看入口方法:
123456789101112131415161718192021222324252627282930313233/** * 确定适用于给定类的candidateAdvisors列表的子列表。 * @param candidateAdvisors 候选Advisors * @param clazz the target class * @return 可以应用于给定类的对象的Advisors的子列表 * (may be the incoming List as-is) */ public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) { if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } List<Adviso ...
Spring-AOP【六】获取指定bean的适配Advisors流程
引言源码分析入口为:AbstractAdvisorAutoProxyCreator的getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource)方法:
123456789101112@Override @Nullable protected Object[] getAdvicesAndAdvisorsForBean( Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) { //找到所有适合自动代理该类的Advisor。 List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName); if (advisors.isEmpty()) { // n ...
Spring-AOP【七】AspectJAdvisorFactory的getAdvisors方法分析
引言AspectJAdvisorFactory:从使用AspectJ注释语法注释的类中创建Spring AOP advisor。首先搬出接口方法定义:
1234567/** * 为指定切面实例上的所有At-AspectJ注释方法构建Spring AOP advisor。 * @param aspectInstanceFactory 切面实例工厂 * (不是切面实例本身,以避免过早实例化) * @return 该类的advisor列表 */ List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory);
他的实现类ReflectiveAspectJAdvisorFactory:
123456789101112131415161718192021222324252627282930313233343536373839404142434445@Override public List<Advisor> getAdvisors(MetadataA ...
Spring-AOP【五】bean实例化的增强核心逻辑
引言通过上一篇文章的分析,我们知道AOP的具体实现在AnnotationAwareAspectJAutoProxyCreator类中。贴上它的类继承关系图:
源码分析入口在其父类AbstractAutoProxyCreator的postProcessAfterInitialization(@Nullable Object bean, String beanName)方法中:
1234567891011121314//如果bean被子类标识为一个代理,则使用已配置的拦截器创建一个代理。 @Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { //根据给定的bean的class和name 获取key,有三种可能:beanName;bean.getClass();"&"+beanName Object ...
Spring-AOP【四】bean实例化的增强入口分析
引言在经过构造ClassPathXmlApplicationContext之后,已经解析了spring-config.xml。
1ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
通过Spring-IOC的分析知道通过实现BeanPostProcessor接口,能在实例化bean之前创建代理,从context中获取实现了BeanPostProcessor接口的实现类:
1234ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");System.out.println(JSONObject.toJSONString(context.getBeansOfType(BeanPostProcessor.class)));Object obj = context.getBea ...
Spring-AOP【三】标签解析AspectJAutoProxyBeanDefinitionParser
引言本篇文章详细分析AspectJAotuProxyBeanDefinitionParser,解析下面标签。
1<aop:aspectj-autoproxy proxy-target-class="false" expose-proxy="false"/>
proxy-target-class属性强制使用CGLIB动态代理则值为true。spring会自动选择动态代理方案,可以不设置。
epose-proxy属性暴露当前的代理对象,springAOP只会拦截public方法,不会拦截provided和private方法,并且不会拦截public方法内部调用的其他方法,也就是说只会拦截代理对象的方法,即增强的是代理对象,而不是原对象。通过设置true,就可以暴露出代理对象,拦截器会获取代理对象,并且将代理对象转换成原对象。从而对内部调用的方法进行增强。
首先看解析器入口方法:
1234567891011@Override @Nullable public BeanDefinition parse(Element element, ...