Spring之IOC和AOP

原创
2018/10/22 19:45
阅读数 655

一、IOC(Inversion of Control)或者依赖注入(Dependency Injection)

1、底层实现原理:反射

2、三大核心接口:

BeanFactory:简单容器系列,只是实现了容器最基本的功能。

ApplicationContext:应用上下文,作为容器的高级形态存在。除了具有基本的功能外,还增加了许多面向框架的特性,同时对应用环境做了许多适配。

WebApplicationContext:JavaWeb项目容器。

3、IOC 容器的初始化过程分为三步骤:Resource 定位、BeanDefinition 的载入和解析,BeanDefinition 注册。

ClassPathResource resource = new ClassPathResource("bean.xml");
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(resource);

    3.1、Resource 定位:获取bean文件的输入流;

    3.2、BeanDefinition 载入和解析:BeanDefinitionReader 读取、解析 Resource 资源,也就是将用户定义的 Bean 表示成 IOC 容器的内部数据结构:BeanDefinition

        a、根据 xml获取相应的 Document 对象(DocumentBuilderFactory文件解析工厂)

        b、对四大标签:import、alias、bean、beans 进行解析,利用反射生成对象

    3.3、BeanDefinition 注册: 向IOC容器注册第二个过程解析得到的 BeanDefinition ,即注入到一个 Map 容器中(IOC 容器内部维护着一个 ConcurrentHashMap 数据结构,key为beanName,value为BeanDefinition)。可以通过bean的lazyinit属性控制依赖关系是在容器初   始化还是第一次调用 getBean() 向容器索要时完成。

二、AOP(Aspect Oriented Programming)

1、介绍:Spring中AOP代理由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理。因此,AOP代理可以直接使用容器中的其它bean实例作为目标,这种关系可由IOC容器的依赖注入提供。

AOP实现的关键在于AOP框架自动创建的AOP代理,AOP代理主要分为静态代理和动态代理,静态代理的代表为AspectJ(AspectJ在编译时就增强了目标对象);而动态代理则以Spring AOP为代表,AOP框架:AspectJ,JBoss AOPJBoss AOP

2、Spring AOP动态代理中的两种主要方式:

JDK动态代理: 其代理对象必须是某个接口的实现,它是通过在运行期间创建一个接口的实现类来完成对目标对象的代理;其核心的两个类是InvocationHandlerProxy, 是由java内部的反射机制来实现的。

CGLIB代理: 实现原理类似于JDK动态代理,只是它在运行期间生成的代理对象是针对目标类扩展的子类。CGLIB是高效的代码生成包,底层是依靠ASM(开源的java字节码编辑类库)操作字节码实现的,性能比JDK强;需要引入包asm.jarcglib.jar

Java 字节码操控框架(ASM和Javassist):在代码里生成字节码,并动态地加载成class对象、创建实例。即在运行期系统中,遵循Java编译系统组织.class文件的格式和结构,生成相应的二进制数据,然后再把这个二进制数据加载转换成对应的类,这样,就完成了在代码中,动态创建一个类的能力了。ASM:在创建class字节码的过程中,操纵的级别是底层JVM的汇编指令级别,这要求ASM使用者要对class组织结构和JVM汇编指令有一定的了解。Javassist:直接使用java编码的形式,不需要了解虚拟机指令。

3、配置方式:

3.1、工厂bean(编码)配置方式:

<bean id="userLogin" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="proxyInterfaces"value="com.aop.proxyFactory.UserLogin"/>
    <property name="target"  ref="target"/>
    <property name="interceptorNames" value="beforeAdviser" />
</bean>

3.2、xml配置方式

<aop:config>里面有一个"proxy-target-class"属性,true代表使用CGLIB生成代理,false(默认)则基于jdk代理

<aop:config>  
   <aop:pointcut id="pointcut" expression="execution(* cn.javass..*.*(..))"/>  
   <aop:aspect ref="aspectSupportBean">  
        <aop:before pointcut-ref="pointcut" method="before"/>  
   </aop:aspect>  
</aop:config>

3、aspect注解

@Aspect
@Service
public class XmlAopDemoUserLog {
    // 配置切点 及要传的参数   
    @Pointcut("execution(* com.demo.service.user.UserService.GetDemoUser(..)) && args(id)")
    public void pointCut(int id){}
    // 配置连接点 方法开始执行时通知
    @Before("pointCut(id)")
    public void beforeLog(int id) {
        System.out.println("开始执行前置通知  日志记录:"+id);
    }
}

三、Spring生命周期

1、BeanFactoryPostProcessor:postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)实例任何bean之前,加载和修改配置信息。
2、Bean的实例化:反射
3、Bean属性注入:反射属性及依赖Bean的注入
4、BeanNameAware:setBeanName(String name)
5、BeanFactoryAware:setBeanFactory(BeanFactory beanFactory)
6、ApplicationContextAware: setApplicationContext(ApplicationContext applicationContext)
7、BeanPostProcessor:postProcessBeforeInitialization(Object bean, String beanName)
8、postProcessBeforeInitialization():afterPropertiesSet()
9、init-method()
10、BeanPostProcessor:postProcessorAfterInitialization(Object bean, String beanName)
11、使用Bean:
12、DisposableBean:destory()
13、destory-method()

说明:

1、容器级生命周期接口(一般称它们的实现类为后处理器):BeanFactoryPostProcessor接口与BeanPostProcessor,它们的作用范围是整个上下文环境。使用方法是单独新增一个类来实现这些接口,那么在处理其他Bean的某些时刻就会回调响应的接口中的方法。

2、Bean生命周期接口:BeanNameAware、BeanFactoryAware、ApplicationContextAware、InitializingBean、DiposableBean,它们的作用范围的Bean范围,即仅仅对实现了该接口的指定Bean有效,所有其使用方法是在要使用该功能的Bean自己来实现该接口。

3、Bean自身的方法init-method()destory-method()。

 

Ref:

http://cmsblogs.com/?p=2790

https://www.jianshu.com/p/94ec7f1c3afd

 

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部