Spring IOC 和 AOP概述

IoC(控制反转,(Inversion of Control):本来是由应用程序管理的对象之间的依赖关系,现在交给了容器管理,这就叫控制反转,即交给了IoC容器,Spring的IoC容器主要使用DI方式实现的。

不需要主动查找,对象的查找、定位和创建全部由容器管理

DI(Dependency Injection) : IOC 的另一种表述方式:即组件以一些预先定义好的方式(例如: setter 方法)接受来自如容器的资源注入. 相对于 IOC 而言,这种表述更直接

1、大量减少了Factory和Singleton的数量,使代码层次更加清晰,主要原因是我们不再查找、定位、创建和管理对象之间的依赖关系了,都交给IoC容器管理了

2、Spring的IoC容器是一个轻量级的容器,没有侵入性,不需要依赖容器的API,也不需要实现一些特殊接口

3、一个合理的设计最好尽量避免侵入性

4、会使我们的框架(Struts和HIbernate)工作的更好

5、提供了AOP声明式服务能力,可以针对POJO对象提供声明式服务能力,如:声明式事务

6、对于资源,如Hibernate Session或JDBC Connection我们不在负责开启和关闭

7、鼓励了我们面向接口编程

8、减少了代码中的耦合(解耦合),将耦合推迟到了配置文件中,发生了变化也更容易控制

AOP(Aspect-Oriented Programming) 

Cross Cutting Concern : 是一种独立服务,它会遍布在系统的处理流程之中

Aspect:对横切性关注点的模块化

Advice:对横切性关注点的具体实现

Pointcut:它定义了Advice应用到哪些JoinPoint上,对Spring来说是方法调用

JoinPoint:Advice在应用程序上执行的点或时机,Spring只支持方法的JoinPoint,这个点也可以使属性修改,如:Aspecj可以支持

Weave:将Advice应用到Target Object上的过程叫织入,Spring支持的是动态织入

Target Object:Advice被应用的对象

Proxy:Spring AOP默认使用JDK的动态代理,它的代理是运行时创建,也可以使用CGLIB代理

Introduction:可以动态的为类添加方法

AOP配置举例:


1

2

3

4

5

6

<aop:config>

    <aop:aspect id="securityAspect" ref="securityHandler">

        <aop:pointcut id="addAddMethod" expression="execution(* add*(..))"/>

        <aop:before method="checkSecurity" pointcut-ref="addAddMethod"/>

    </aop:aspect>

</aop:config>

  

1. spring bean的作用域 ,scope取值:

singleton:默认值,每次调用getBean()向IoC容器中取得对象是相同

prototype:每次调用getBean()向IoC容器中取得对象是不相同

2. 什么是属性编辑器和作用?

将spring配置文件中的字符串转换成相应的java对象

spring内置了一些属性编辑器,也可以自定义属性编辑器

3. 如何自定义属性编辑器?

继承PropertyEditorSupport

覆盖setAsText()方法

将自定义的属性编辑器注入到spring中

4.了解关于多配置文件的读取方式

可以采用数组

可以采用*匹配模式

5. 如何减少spring的配置文件

通过<bean>标签将公共的配置提取出来,然后指定<bean>标签中的abstract属性为true,在其他<bean>标签中指定其parent即可

6. spring默认在创建BeanFactory时,将配置文件中所有的对象实例化并进行注入

但可以采用相关的属性延迟配置文件的初始化,如:default-lazy-init="true"

7. 在web.xml文件中配置ContextLoaderListener,让Web Server在启动的时候将BeanFactory放到ServletContext中    


1

2

3

4

5

6

7

8

9

10

<context-param>

       <param-name>contextConfigLocation</param-name>

       <param-value>classpath:applicationContext-*.xml</param-value>

</context-param>

<listener>

        <listener-class>

               org.springframework.web.context.ContextLoaderListener

        </listener-class>

</listener>

spring的配置文件applicationContext.xml的默认地址在WEB-INF下,只要在web.xml中加入代码 : org.springframework.web.context.ContextLoaderListener , spring

就会被自动加载。根据Spring框架的API描述,有以下四种方法配置applicationContext.xml文件路径

1). /WEB-INF/applicationContext.xml

2). com/config/applicationContext.xml

3). file:C:/javacode/springdemo/com/config/applicationContext.xml

4). classpath:com/config/applicationContext.xml

注:以上路径只是举例,具体使用还是要针对真是项目的。开发过程中,如果spring的配置文件applicationContext.xml未加载的话,一般回报这样的错误 :

Could not open ServletContext resource [/WEB-INF/applicationContext.xml]

8. 声明式事务配置

1). 配置SessionFactory

2). 配置事务管理器

3). 事务的传播特性

4). 那些类那些方法使用事务

9. 编写业务逻辑方法

1). 继承HibernateDaoSupport类,使用HibernateTemplate来持久化,HibernateTemplate是Hibernate Session的轻量级封装

2). 默认情况下运行期异常才会回滚(包括继承了RuntimeException子类),普通异常是不会滚的

3). 编写业务逻辑方法时,最好将异常一直向上抛出,在表示层(struts)处理

4). 关于事务边界的设置,通常设置到业务层,不要添加到Dao上

10.了解事务的几种传播特性

 1). PROPAGATION_REQUIRED: 如果存在一个事务,则支持当前事务。如果没有事务则开启

2). PROPAGATION_SUPPORTS: 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行

3). PROPAGATION_MANDATORY: 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。

4). PROPAGATION_REQUIRES_NEW: 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。

5). PROPAGATION_NOT_SUPPORTED: 总是非事务地执行,并挂起任何存在的事务。

6). PROPAGATION_NEVER: 总是非事务地执行,如果存在一个活动事务,则抛出异常

7). PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行

11. Spring事务的隔离级别

1). ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.另外四个与JDBC的隔离级别相对应

2). ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。

3). ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据

4). ISOLATION_REPEATABLE_READ:它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。

这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了

免下面的情况产生(不可重复读)。

5). ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。

12. AOP的实现

1). 如果目标对象实现了接口,在默认情况下会采用JDK的动态代理实现AOP

2). 如果目标对象实现了接口,也可以强制使用CGLIB生成代理实现AOP

3). 如果目标对象没有实现接口,那么必须引入CGLIB,spring会在JDK的动态代理和CGLIB代理之间切换

CGLib所创建的动态代理对象的性能比JDK的高大概10倍,但CGLib在创建代理对象的时间比JDK大概多8倍(真的吗?),所以对于singleton的代理对象或者具有实例池的代理,因为无需重复的

       创建代理对象,所以比较适合CGLib动态代理技术,反之选择JDK代理。值得一提的是由于CGLib采用动态创建子类的方式生成代理对象,所以不能对目标类中final的方法进行代理。

       CGLIB 需要引入新jar包。

参考:http://www.xuebuyuan.com/324257.html

13. 如何强制使用CGLIB生成代码?

加入CGLIB库,SPRING_HOME/lib/cglib/*.jar

加入如下配置,强制使用CGLIB代理

<aop:aspectj-autoproxy proxy-target-class="true"/>

14. JDK动态代理和CGLIB代理的区别?

JDK动态代理对实现了接口的类进行代理

CGLIB代理可以对类代理,主要对指定的类生成一个子类,因为是继承。我们的目标最好不要使用final声明

15. hibernate 事务查询配置为只读(read-only=true),不会清理缓存,有优化

16. 使用外部属性文件

Spring 提供了一个 PropertyPlaceholderConfigurer 的 BeanFactory 后置处理器, 这个处理器允许用户将 Bean 配置的部分内容外移到属性文件中.

Spring 2.5 之后: 可通过 <context:property-placeholder> 元素简化: <beans> 中添加 context Schema 定义在配置文件中加入如下配置:


1

2

3

4

5

6

7

8

9

10

11

12

<!-- 导入资源文件 -->

<context:property-placeholder location="classpath:db.properties"/>

<!-- 配置 C3P0 数据源 -->

<bean id="dataSource"

        class="com.mchange.v2.c3p0.ComboPooledDataSource">

       <property name="user" value="${jdbc.user}"></property>

       <property name="password" value="${jdbc.password}"></property>

       <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>

       <property name="driverClass" value="${jdbc.driverClass}"></property>

       <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>

       <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>

</bean>

17. 组件扫描:

<context:component-scan base-package="com.tgb.web.controller.annotation"> </context:component-scan>   

特定组件包括(类):

@Component: 基本注解, 标识了一个受 Spring 管理的组件

@Respository: 标识持久层组件

@Service: 标识服务层(业务层)组件

@Controller: 标识表现层组件

对于扫描到的组件, Spring 有默认的命名策略: 使用非限定类名, 第一个字母小写. 也可以在注解中通过 value 属性值标识组件的名称

当在组件类上使用了特定的注解之后, 还需要在 Spring 的配置文件中声明 <context:component-scan> :

1). base-package 属性指定一个需要扫描的基类包,Spring 容器将会扫描这个基类包里及其子包中的所有类.

 2). 当需要扫描多个包时, 可以使用 逗号分隔.

3). 如果仅希望扫描特定的类而非基包下的所有类,可使用 resource-pattern 属性过滤特定的类,示例:

4). <context:include-filter> 子节点表示要包含的目标类,<context:exclude-filter> 子节点表示要排除在外的目标类

<context:component-scan> 下可以拥有若干个 <context:include-filter> 和 <context:exclude-filter> 子节点

18. 使用 @Autowired 自动装配 Bean:

      @Autowired 注解自动装配具有兼容类型的单个 Bean属性。构造器, 普通字段(即使是非 public), 一切具有参数的方法都可以应用@Authwired 注解。默认情况下, 所有使用 @Authwired 注解

      的属性都需要被设置. 当 Spring 找不到匹配的 Bean 装配属性时, 会抛出异常, 若某一属性允许不被设置, 可以设置 @Authwired 注解的 required 属性为 false

默认情况下, 当 IOC 容器里存在多个类型兼容的 Bean 时, 通过类型的自动装配将无法工作. 此时可以在 @Qualifier 注解里提供 Bean 的名称. Spring 允许对方法的入参标注 @Qualifiter 已指定注入 Bean 的名称

@Authwired 注解也可以应用在数组类型的属性上, 此时 Spring 将会把所有匹配的 Bean 进行自动装配.

@Authwired 注解也可以应用在集合属性上, 此时 Spring 读取该集合的类型信息, 然后自动装配所有与之兼容的 Bean.

@Authwired 注解用在 java.util.Map 上时, 若该 Map 的键值为 String, 那么 Spring 将自动装配与之 Map 值类型兼容的 Bean, 此时 Bean 的名称作为键值

19. 整合多个配置文件:

Spring 允许通过 <import> 将多个配置文件引入到一个文件中,进行配置文件的集成。这样在启动 Spring 容器时,仅需要指定这个合并好的配置文件就可以。

import 元素的 resource 属性支持 Spring 的标准的路径资源

 

配置文件举例: 

 1 <?xml version="1.0" encoding="UTF-8"?>
 2
 3 <beans xmlns="http://www.springframework.org/schema/beans"
 4          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5          xmlns:aop="http://www.springframework.org/schema/aop"
 6          xmlns:tx="http://www.springframework.org/schema/tx"
 7          xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
 8            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
 9            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
10     <!-- 配置SessionFactory -->
11     <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
12         <property name="configLocation">
13             <value>classpath:hibernate.cfg.xml</value>
14         </property>
15     </bean>
16
17     <!-- 配置事务管理器 -->
18     <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
19         <property name="sessionFactory">
20             <ref bean="sessionFactory"/>
21         </property>
22     </bean>
23
24     <!-- 那些类那些方法使用事务.两种方式。
25          <aop:config>
26                 <aop:advisor advice-ref="txAdvice" pointcut="execution(* cn.itcast.ssm.service.impl.*.*(..))"/>
27         </aop:config>
28         -->
29     <aop:config>
30         <aop:pointcut id="allManagerMethod" expression="execution(* com.bjpowernode.drp.service.*.*(..))"/>
31         <aop:advisor pointcut-ref="allManagerMethod" advice-ref="txAdvice"/>
32     </aop:config>
33
34     <!-- 事务的传播特性 -->
35     <tx:advice id="txAdvice" transaction-manager="transactionManager">
36         <tx:attributes>
37             <tx:method name="add*" propagation="REQUIRED"/>
38             <tx:method name="del*" propagation="REQUIRED"/>
39             <tx:method name="modify*" propagation="REQUIRED"/>
40             <tx:method name="*" propagation="REQUIRED" read-only="true"/>
41         </tx:attributes>
42     </tx:advice>
43 </beans>
时间: 2024-10-18 17:29:04

Spring IOC 和 AOP概述的相关文章

Spring IOC及AOP学习总结

一.Spring IOC体系学习总结: Spring中有两个容器体系,一类是BeanFactory.另一类是ApplicationContext.BeanFactory提供了基础的容器功能.ApplicationContext则是基于BeanFactory建立的一套更加丰富的容器体系,基于ApplicationContext构建了Spring AOP体系(基于AOP体系又构建了声明式事务模型),I18n的支持,基于观察者模式的事件模型,多渠道的Bean资源的载入(比如从文件系统,从interne

Spring IOC 和 AOP

Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架. 1.控制反转(IOC)/依赖注入(DI): 在传统的程序设计中,当调用者须要被调用者的协助时,通常由调用者来创建被调用者的实例. 但在spring里创建被调用者的工作不再由调用者来完毕.因此控制反转(IoC),为什么称为反转呢?反转是相对于正向而言的,那么什么算是正向的呢?考虑一下常规情况下的应用程序,假设要在A里面使用C,你会怎么做呢?当然是直接去创建C的对象,也就是说,是在A类中主动去获取所须要的外部资源C.这样的

spring - ioc和aop

1.程序中为什么会用到spring的ioc和aop 2.什么是IOC,AOP,以及使用它们的好处,即详细回答了第一个问题 3.原理 关于1: a:我们平常使用对象的时候,一般都是直接使用关键字类new一个对象,那这样有什么坏处呢?其实很显然的,使用new那么就表示当前模块已经不知不觉的和 new的对象耦合了,而我们通常都是更高层次的抽象模块调用底层的实现模块,这样也就产生了模块依赖于具体的实现,这样与我们JAVA中提倡的面向接口面向抽象编程是相冲突的,而且这样做也带来系统的模块架构问题.很简单的

spring ioc和aop理解

spring IOC 1.目的:就是解决程序间的依赖关系 2.原理:通过反射原理将我们控制层中的 dao层. service层类以工厂模式在static代码块中实现加载后存放入map中 , 并实现单列 . 原文地址:https://www.cnblogs.com/cwone/p/11939192.html

Spring+IOC(DI)+AOP概念及优缺点

Spring pring是一个轻量级的DI和AOP容器框架. 说它轻量级有一大部分原因是相对与EJB的(虽然本人从没有接触过EJB的应用),重要的是,Spring是非侵入式的,基于spring开发的应用一般不依赖于spring的类. 容器:Spring是个容器,因为它包含并且管理应用对象的生命周期和配置.如对象的创建.销毁.回调等. 框架:Spring作为一个框架,提供了一些基础功能,(如事务管理,持久层集成等),使开发人员更专注于开发应用逻辑. Spring的优点1.降低了组件之间的耦合性 ,

对Spring IOC和AOP的理解

控制反转(IOC)是什么?(理解好Ioc的关键是要明确"谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了") 1.Ioc-Inversion of Control:即"控制反转",不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制. 2.谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象:而IoC是有专门一

Spring IoC和AOP使用扩展(二)

一.IOC的实现方式: Set注入:熟悉必须有公共set方法: 构造器注入:可以根据构造器参数名称.下标注入: p命名空间注入:要求有set方法: 内部bean的实现: <bean id="userService" class="com.service.UserService"> <property name="userDao"> <bean class="com.dao.UserDao">

关于spring,IOC和AOP的解析原理和举例

引用自:https://blog.csdn.net/paincupid/article/details/43152397 IOC:就是DAO接口的实现不再是业务逻辑层调用工厂类去获取,而是通过容器(比如spring)来自动的为我们的业务层设置DAO的实现类.这样整个过程就反过来,以前是我们业务层主动去获取DAO,而现在是DAO主动被设置到业务逻辑层中来了,这也就是反转控制的由来.通过IOC,我们就可以在不修改任何代码的情况下,无缝的实现数据库的换库迁移,当然前提还是必须得写一个实现特定数据库的D

对于Spring IOC 和 AOP 简单理解

IOC IOC(Inversion Of Controll,控制反转)是一种设计思想,将原本在程序中手动创建对象的控制权,交由给Spring框架来管理.IOC容器是Spring用来实现IOC的载体,IOC容器实际上就是一个Map(key, value),Map中存放的是各种对象. 这样可以很大程度上简化应用的开发,把应用从复杂的依赖关系中解放出来.IOC容器就像是一个工厂,当需要创建一个对象,只需要配置好配置文件/注解即可,不用考虑对象是如何被创建出来的,大大增加了项目的可维护性且降低了开发难度