Spring学习
1.Spring的三种实例化Bean的方式
1.1使用类构造器实例化
a.id:给bean取的一个名字,bean标签还有个name属性和id一样给bean取名字,但是id是具有唯一性,切id属性是xml文件标签的固有的属性,xml解析器会校验该属性(其中包括唯一性,以及值的校验,值不能出现一些字符),项目中可能取名字会用到特殊字符 时可以使用name属性。
b.class:类所在的包的完整路劲。
1.2.使用静态工厂方法实例化
1.3.使用实例工厂方法实例化
1.4.启动spring容器和获取bean的方法
2.配置Spring管理的bean的作用域
交给spring管理的bean默认是使用单例模式,如果需要使用原型那么可以使用bean标签的scope属性:
scope="prototype"时每次获取bean的时候都会返回一个新的对象,并且在我们调用getBean方法时才初始化bean
3.Spring管理的Bean的生命周期
3.1.spring在启动容器的时候就帮我们初始化了bean,如果希望启动时不初始化,可以使用 lazy-init属性:
3.2.有时候我们希望bean在初始化的时候执行某个方法(比如初始化一些资源),以前我们可以在构造方法中添加一个可以执行的方法:
或者添加构造代码块
现在我们可以使用spring给我们提供的 init-method:
3.3.在类销毁(关闭spring容器的时候)的时候也可以指定我们需要的运行方法使用destroy-method属性
4.Spring依赖注入(配置xml文件方式)
4.1通过属性的setter注入,使用property标签
(1)外部bean方式
(2)通过内部bean的方式注入
(3)Spring装配基本属性
(4)Spring装配各种集合类型的属性
(5) 注入properties
4.2.使用构造器装配属性
5.Spring依赖注入(注解方式)
使用注解开发需要Spring的支持,所以需要为Spring注册对注解进行解析的解析器,可以通过使用以下标签注册解析器:
5.1.用@Resource注解完成属性装配
Resource可以注解到属性或者属性的setter方法上,默认是使用名称进行查找,如果没有指定名称那么取属性的名称或者setter方法参数的名称,如果通过名称没有找到再通过属性的类型进行查找。
注:Resourse一旦指明了name属性就只按照名称查找
5.2.用@Autowired注解与自动装配
Autowired注解是按照类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许为Null,可以通过设置它 required属性为 false 如果我们想使用名称装配可以结合@Qualifier注解一起使用如:
6.Spring自动扫描和管理Bean
1.如果希望Spring通过扫描包的形式帮我加载bean,需要在xml中配置
<context:component-scan base-package="com.liyou.spring.study"/>,base-package是告诉Spring需要扫描的包以及子包。该标签配置后会帮我们注册很多的注解解析器,所以在不配置<context:annotation-config/>标签时也可以使用注解.
2.那么Spring是怎么知道哪些bean需要帮我加载啦?可以通过一下几个注解告诉Spring.
@Service用于标注业务层组件
@Repository用于标注数据访问层组件,就是我这里的Dao组件
@Controller用于标注控制层的组件,如SpringMVC中的控制器组件
@Component泛指组件,当一个组件不好归类的时候,我们可以使用这个注解进行标注
其中我可以给一些参数如@Service 指定一个value值,这个值就是Spring帮我们加载bean给bean取的名字,如果没有指定这个值,默认值为被标注注解类的简单类名。
3.如果需要指定bean单列还是原型可以使用@Scope
4.如果需要指定bean加载前执行某个方法,可以使用@PostConstruct;指定bean被摧毁时执行的方法可以使用@PreDestrop
7.Spring实现AOP
7.1.Spring的注解方式实现AOP入门
7.1.1配置文件
打开spring对aop的支持,在xml配置文档中配置标签:<aop:aspectj-autoproxy/>,现在就可以进行aop的注解开发
7.1.2 开发AOP程序
a.首先我们需要定义一个切面(一个bean),使用@Aspect
b.在切面中定义切入点(对业务bean里面的哪些方法进行拦截)@Pointcut
注意:spring中aop是面向方法的,所以pointcut就是切入点的名称
c.以及定义通知(拦截到方法时我们需要处理的事情)
7.1.3如果我们希望得到方法的参数
7.1.4如果我们要获取方法的返回值
7.1.5同样发生异常的时候需要获得信息
throwing可以指定
注意around和afterthrowing一起使用时如果在around中捕获了异常那么afterthrowing是不会处罚的
7.2.Spring配置文件实现AOP
7.2.1 <aop:config>标签的使用
通过修改expression的属性值execution(* com.liyou.spring.study.service..*.*(..)) 可以定义不同的返回值和参数的类型来拦截不同的方法,spring会为定义在com.liyou.spring.study.service..* 下的类创建代理对象,如果类实现了接口就通过JDK 的proxy来创建代理对象,如果没有实现接口就通过cglib来创建代理对象.
8.搭建和配置Spring与jdbc整合的环境
8.1.配置数据源
8.2.使用Spring为我们提供的工具类JdbcTemplate类来对数据库的CRUD操作
使用注入方式注入到我们的业务bean中
8.3 配置spring为我们提供的事务管理类
8.3.1我们采用注解方式@Transactional来声明事务,需要打开spring的事务管理支持,使用<tx:annotation-driven transaction-manager="txManager"/>
spring默认下对运行期(unchecked)的异常会回滚事务,对checked的异常不会回滚事务,及如果业务方法是方法签名上有使用了throws向外抛出了异常,这样的方法发生异常是不会回滚事务的。
8.3.2我们可以通过注解来修改这种默认的方式
和rollbackFor、noRollbackFor相同作用的注解可以使用rollbackForClassName、noRollbackForClassName这两个注解可以指定一个String[]类型的参数,参数值为类的简单类名
8.3.3 可以通过注解参数propagation = Propagation.NOT_SUPPORTED来指定事务的传播行为为不支持事务
Propagation给我们提供了一下几种事务传播行为:
a.REQUIRED,业务方法需要在一个事务中运行。如果方法运行时,已经处在一个事务中,那么加入到该事务,否则为自己创建一个新的事务。
b.SUPPORTS,这一事务属性表明,如果业务方法在某个事务范围内被调用,则方法成为该事务的一部分。如果业务方法在事务范围外被调用,则方法在没有事务的环境下执行。
c.MANDATORY,该属性指定业务方法只能在一个已经存在的事务中执行,业务方法不能发起自己的事务,如果业务方法在没有事务的环境下被调用,容器就会抛出异常。
d.REQUIRES_NEW,属性表明不管是否在事务,业务方法总会为自己发起一个新的事务。如果方法已经运行在一个事务中,则原来的事务会被挂起,新的事务会被创建,直到方法执行结束,新的事务才算结束,原来的事务才会被恢复执行。
e.NOT_SUPPORTED,声明方法不需要事务。如果方法没有关联到一个事务,容器不会为它开启事务,如果方法在一个事务中被调用,该事务会被挂起,在方法调用结束后,原先的事务便会恢复执行。
f.NEVER,指定业务方法绝对不在事务范围内执行,如果业务方法在某个事务中执行,容器会抛出异常,只有业务方法没有关联到任何事务,才能正常执行。
g.NESTED;如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动的事务,则按REQUIRED属性执行,它使用了一个单独的事务,这个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响,它只对DataSourceTransactionManager事务管理器起效。
8.4.使用Spring配置文件实现事务管理