本文共 3451 字,大约阅读时间需要 11 分钟。
Spring Core最核心的部分
依赖注入 ; 依赖检查 ; 自动装配 ; 支持集合 ; 指定初始化和销毁方法 ; 回调方法
BeanFactory
ApplicationContext(继承多个接口)
XML配置方式
笼统说就是在定义好实体类之后,在applicationContext.xml文件中配置bean信息(包含id和对应的class),这样相当于把bean装载到Spring容器中了。 然后可以通过读取配置信息得到ApplicationContext的对象,调用它的getBean方法(里面可以根据类型查找Bean或者根据id查找)得到对应的bean。依赖注入的实现:set方法、构造函数、注解、接口(不推荐)
Set方法: 在需要注入的类里定义被注入类,然后通过set方法将被注入类传参,同时applicationContext配置文件中添加下面内容 构造函数: 在需要注入的类里定义被注入类,然后通过构造函数将被注入类传参,同时applicationContext配置文件中添加下面内容 基于注解 @Component 和@CompomentScan搭配扫描装配Bean。同时可以在实体类里用@Value初始化对象的属性。 使用@Autowired实现依赖注入 基于Java类 先写一个配置信息类用@Configuration标注,然后编写一个返回Bean实例的方法并用@Bean标注。 使用@Autowired实现依赖注入AbstractBeanFactory中的getBean(),又调用了doGetBean()
1.通过transformedBeanName提取beanName 2.根据getSingleton(beanName)获取单例bean(也就是缓存中) 3.实例化bean 4.如果获取不到bean就检测parentBeanFactory 5.递归初始化依赖的bean 6.创建beansingleton:
Spring的默认作用域,容器里拥有唯一的Bean实例 prototype: 针对每个getBean请求,容器都会创建一个Bean实例 request: 会为每个Http请求创建一个Bean实例 session: 会为每个session创建一个Bean实例 globalSession: 会为每个全局Http Session创建一个Bean实例,该作用域仅对Portlet有效• Bean容器找到配置文件中Spring Bean的定义。
• Bean容器利用Java Reflection API创建一个Bean的实例。 • 如果涉及到一些属性值 利用set方法设置一些属性值。 • 如果Bean实现了BeanNameAware接口,调用setBeanName()方法,传入Bean的名字。 • 如果Bean实现了BeanClassLoaderAware接口,调用setBeanClassLoader()方法,传入ClassLoader对象的实例。 • 如果Bean实现了BeanFactoryAware接口,调用setBeanClassLoader()方法,传入ClassLoader对象的实例。 • 与上面的类似,如果实现了其他*Aware接口,就调用相应的方法。 • 如果有和加载这个Bean的Spring容器相关的BeanPostProcessor对象,执行postProcessBeforeInitialization()方法 (对实例化的bean添加一些自定义的处理逻辑,AOP,前置初始化方法) • 如果Bean实现了InitializingBean接口,执行afterPropertiesSet()方法。 • 如果Bean在配置文件中的定义包含init-method属性,执行初始化相关工作。 • 如果有和加载这个Bean的Spring容器相关的BeanPostProcessor对象,执行postProcessAfterInitialization()方法 (AOP,后置初始化方法) • 当要销毁Bean的时候,如果Bean实现了DisposableBean接口,执行destroy()方法。 • 当要销毁Bean的时候,如果Bean在配置文件中的定义包含destroy-method属性,执行指定的方法。面向切面编程AOP是基于关注点分离的技术实现的,主要是将业务逻辑代码和通用化代码(日志,事务等)的关注点分离。通用化代码的实现就是(切面)。业务功能代码和切面代码分开后,架构将高内聚低耦合。为了确保功能的完整性,切面最终需要被合并到业务中(织入)。
Aspect:通用代码的实现 Target:被织入通用代码的对象 Join Point:可以作为切入点的机会 Pointcut:切入点 Adivice:通知,类里的方法 Weaving:Aop的实现过程编译时织入:需要特殊的Java编译器,如AspectJ
类加载织入:需要特殊的Java编译器,如AspectJ 运行时织入:Spring采用的方式,通过动态代理实现由AopProxyFactory根据AdvisedSupport对象的配置来决定。默认策略如果目标类是接口,则用JDKProxy来实现,否则用Cglib。
JDKProxy的核心:InvocationHandler接口和Proxy类(反射) Cglib:以继承的方式动态生成目标类的代理。真实实现类的逻辑包含在了getBean方法里。
getBean方法返回的实际上是Proxy的实例。 Proxy实例是Spring采用JDK Proxy或CGLIB动态生成的。Spring AOP属于运行时增强(动态),基于代理;AspectJ AOP属于编译时增强(静态),基于字节码。
Spring AOP已经集成了AspectJ,AspectJ应该算的上是Java生态系统中最完整的AOP框架了。AspectJ相比于SpringAOP功能更加强大,但是Spring AOP相对来说更简单,如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择AspectJ,它比Spring AOP快很多。转载地址:http://qnerj.baihongyu.com/