Spring 框架之IOC、AOP

Spring 框架之IOC、AOP

spring概念

spring是项目中对象的容器.用来管理项目中的所有对象.

创建对象,并维护对象间的关系AOP整合代理技术,实现AOP思想spring可以整合几乎任何第三方框架,作为项目中的粘合剂.

IOC&DI概念

IOC:反转控制,创建对象的方式被反转,从我们自己创建变为程序创建.DI:依赖注入,是技术,可以将依赖属性注入到对象.构造注入|set方法注入.IOC的实现需要依赖DI技术.

BeanFactory&ApplicationContext

BeanFactory接口 BeanFactory是spring框架初代接口. BeanFactory是ApplicationContext父接口. BeanFactory是获得对象时才创建对象.ApplicationContext接口 ApplicationContext是后期发展出的接口. ApplicationContext的功能要更加强大. ApplicationContext是启动时默认立刻创建容器中所有对象,获得时直接返回

AOP思想

纵向重复,横向抽取.spring封装了代理技术,通过代理技术来体现aop思想.我们使用代理体现aop时,不需要我们自己书写代理代码.spring帮我们完成.

spring框架搭建

导包

4个核心包,core、bean、context、exception2个日志包,apache.commons.loggin、apache.log4j

准备对象

创建一个类

创建spring配置文件

在src目录下创建applicationContext.xml

导入4个约束(schema)beans、context、tx、aop

<bean>

<bean>

<bean>

<property>

配置spring容器随项目启动

原则:一个web项目启动只创建一个spring容器.

操作:

方案一:将spring容器的创建放入静态代码块中.该访问属于自己手动创建容器,容器与web项目没有关联,不推荐.

方案二:spring利用监听器(ServletContext对象创建与销毁监听器)来创建容器.

<listener>

<listener-class>org.springframework.web.context.ContextLoaderListener/<listener-class>

<context-param>

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

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

原理:ContextLoaderListener继承了ServletContextListener,ServletContextListener监听ServletContext的创建与销毁。

代码测试

SE环境测试

//1.创建spring容器

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

//2.获取User对象

User user = ac.getBean("user");

获得spring容器及容器中对象

Web环境下

//1.获得Application域对象

ServletContext sc = ServletActionContext.getServletContext();

//2.调用工具方法从域中取出对象

ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(sc);

//3.获得CustomerService

us = (UserService) ac.getBean("userService");

spring配置详解(xml)

基础配置

bean元素:将对象交给spring容器管理

name属性:对象的名字,spring根据该名字获得。id属性:对象的名字,spring根据该名字获得。name属性与id属性区别: 1.id出现时间较早. 2.id属性必须符合id规范:唯一不能使用特殊字符. 3.name属性:可以重复(不推荐重复),也可以使用特殊字符.class属性:对象的完整类名。scope属性:决定对象的作用域,生命周期。singleton(默认值):单例,容器启动时创建单例对象,容器销毁时才销毁单例对象.prototype:原型多例,启动时不会创建,每次获得时都会创建新的对象,对象不会放入容器的管理.request:web环境下的属性,对象的生命周期为一次请求.session:web环境下的属性,对象的生命周期为一次会话.init-method|desotory-method属性:指定对象的生命周期。init-method:指定对象的初始化方法,会在构造方法调用之后调用.destory-method:指定对象的销毁方法,会在容器销毁对象之前调用.xml配置<bean>

sping创建对象方法

静态工厂

//静态工厂

public class UserFactory{

public static User getUser(){

return new User();

}

}

xml配置文件

<bean>

动态工厂

//动态工厂

public class UserFactory{

public User getUser2(){

return new User();

}

}

xml配置文件

<bean>

<bean>

构造方法(推荐)

<bean>

spring中的DI(依赖注入)

构造方法注入

constructor-arg:指定构造参数

定位属性: name属性:参数名 index属性:指定参数在参数列表中的索引 type属性:指定参数类型注入属性: value属性:参数值 ref属性:注入引用类型<bean> <constructor-arg> <constructor-arg> <constructor-arg>

set方法注入

property标签<bean> <property> <property> <property>p名称空间

导入p名称空间

xmlns:p="http://www.springframework.org/schema/p"

p:属性名= | p:属性名-ref=

<bean>

SPEL表达式

SPEL:spring expression language spring 表达式语言,只能引用属性,不能引用对象.

在配置文件中使用#{spel}来引用其他Bean的属性值.

<bean>

<property>

<property>

复杂类型注入

Array

1.只有一个值可以直接使用value|ref

<property>

2.如果多个值,元素

<property>

<array>

<value>pro/<value>

List

1.只有一个值可以直接使用value|ref

<property>

2.如果多个值,元素

|-

|-

<property>

<list>

<value>c/<value>

Map

|-填写键值对

<property>

<entry>

<entry><entry>/<entry>

<entry>

Properties

|-填写键值对

<property>

<props>

<prop>

<prop>

spring配置详解(注解)

准备工作

导包

|4+2

|spring-aop

导入约束

spring-context-4.2.xsd

开启注解配置

<component-scan>

注解

注册对象

@component(“user”)

@controller(“user”)

@service(“user”)

@Repository(“user”)

指定对象域作用域

@Scope(“singleton”)

指定对象生命周期

@PostConstruct 初始化

@PreDestory 销毁

值注入

@value

1.成员变量,直接为成员变量赋值

2.set方法,调用set方法赋值

注入引用类型

1.@AutoWired根据类型自动装配

2.@AutoWired和@Qulifier配合,@Qualifier(“car”)

3.@Resource直接指定注入的对象名,@Resource(name=”car”)

spring整合JDBC(JDBCTemplate)

spring框架提供一个可以完成jdbc操作的对象,该对象可以放置到spring容器中.

spring准备的操作数据库的类,与QueryRunner类的设计与使用几乎完全相同.

导包

4+2spring-jdbc、spring-tx数据库驱动、c3p0连接池

JDBCTemplate工具类

jt.update(String sql,Object…params)增删改public void save(User u){ String sql ="insert into t_user value(null,?) "; getJdbcTemplate().update(sql,user.getName);}jt.queryForObject(sql,class,params),查询单个值,并指定返回值类型//查询总数public Integer getTotalCount(){ String sql = "select Count(*) from t_user "; getJdbcTemplate().queryForObject(sql,Integer.class);}jt.queryForObject(sql,rowMapper,params),执行查询,并手动封装结果到对象中.返回单个对象//根据id查对象public User getById(Integer id){ String sql = "select * from t_user where id=?"; return getJdbcTemplate().QueryForObject(sql,new RowMapper<user>(){/<user> public User mapRow(ResultSet rs,int index ) throws SQLException{ User user = new User(); user.setId(rs.getInt("id")); user.setName(rs.getString("name")); return user; } },id);}jt.query(sql,rowMapper,params),执行查询,手动封装结果,返回List//查询所有的Userpublic List<user> getAll(){/<user> String sql = "select * from t_user"; return getJdbcTemplate().QueryForObject(sql,new RowMapper<user>(){/<user> public User mapRow(ResultSet rs,int index) throws SQLException{ User user = new User(); user.setId(rs.getInt("id")); user.setName(rs.getString("name")); return user; } });}

JdBCDaoSupport

继承JdbcDaoSupport,减少一层依赖关系.源码中已经帮我们接收JdbcTemplate

好处:可以减少一级依赖关系.直接将连接池对象注入给Dao即可。

使用DB.properties管理连接信息

在src下创建properties文件,文件配置数据库信息spring配置文件中读取:在配置中引用,${key}

spring中aop开发

aop&代理

spring中封装的代理技术

动态代理局限性:生成代理类时必须基于接口.生成的代理对象实际上就是接口的实现类. spring中的aop是希望能够对所有对象生成代理的.基于该动态代理原则会导致 项目中很多类无法生成代理.CGLib代理spring为了能够对项目中所有类生成代理.所以引入了cglib这个第三方代理技术.该代理技术的特点是.对目标对象生成代理时,代理对象是被代理对象的子类. hibernate中应用了CGLib代理,懒加载技术中返回的就是cglib代理对象.

aop中的名称解释

aop联盟制定规范

连接点 join point:目标对象中所有可以增强的方法.切点 point cut:已经或即将增加的方法.通知 advice:我们需要对目标方法增强的代码.目标对象 target:我们需要增强的对象代理对象 proxy:将通知应用到目标对象生成的对象织入 weaving:将通知织入到目标对象的过程.切面 aspect|advistor:切点+通知

springAOP开发步骤(注解)

导包目标对象通知对象配置注解

注解详解

xml中配置

注册目标对象<bean>注册通知对象<bean>开启使用注解配置aop<aspectj-autoproxy>

代码中配置注解

@Aspect 表示该类是通知类@Aspect pbublic class MyAdvice{}@Before(“execution(表达式)”) 前置通知@Around(“execution(表达式)”) 环绕通知@AfterRunner(“execution(表达式)”) 后置通知@After(“execution(表达式)”) 后置通知,不管是否抛异常,都执行@AfterThrowing(“execution(表达式)”) 异常拦截通知//注册切点@Pointcut(execution(* cn.it.service.impl.*ServiceImpl.*(..)))public void myPc(){}//前置通知@Before("MyAdvice.myPc()")public void before(){}

springAOP开发步骤(xml)

导包目标对象通知对象配置xml

xml配置详解

<config>

<bean>

<bean>

<pointcut>

<aspect>

<before>

<around>

<after>

<after-returning>

<after-throwing>

Spring中的aop事务管理

事务属性

传播行为(PROPAGATION)默认选择REQUIRED是否只读(only-read)true|false隔离级别

springAOP事务管理(XML) ###

导包创建Dao层对象创建Service层对象创建Spring配置文件

spring文件配置详解

<property-placeholder>

<bean>

<property>

<property>

<property>

<property>

<bean>

<property>

<bean>

<property>

配置事务

引入tx约束

<bean>

<property>

<advice>

<attributes>

<config>

<pointcut>

<aspect>

springAOP事务管理(注解) ###

导包创建Dao层对象创建Service层对象创建Spring配置文件

spring文件配置详解

<property-placeholder>

<bean>

<property>

<property>

<property>

<property>

<bean>

<property>

<bean>

<property>

配置注解//使用注解管理事务 @Transactional(paragation=Paragation.REQUIRED,readOnly=false,isolaction=Isolaction.REPEATABLE_READ) public class UserServiceImpl implements UserService{@Transactional(paragation=Paragation.REQUIRED,readOnly=true,isolaction=Isolaction.REPEATABLE_READ)public void transaction()}

spring整合hibernate、struts2

导包

hibernate lib下requiredstruts2 apps下struts2-blank(删除与hibernate相同的包)spring core、context、bean、exception、log4j、loggingspring-jdbc、spring-tx、spring-orm数据库驱动、c3p0连接池spring-aop、spring-aspectaspectj织入、aop联盟spring-webspring-test、junit4web jstl

整合spring到web项目

配置监听器,让spring随项目的启动而创建容器

<listener>

<listener>org.springframework.web.context.ContextLoaderListener/<listener>

<context-param>

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

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

准备spring配置文件

在src目录下创建applicationContext.xml,导入4个约束,bean、context、tx、aop

<bean>

<bean>

<property>

<bean>

<property>

整合struts2到web项目

创建Action

创建Action的三种方式 pojo(普通java对象,不需要实现任何接口|任何类)实现Action继承ActionSupport获取表单数据的三种方式 属性驱动对象驱动模型驱动

创建配置文件

<struts>

<package>

<action>

<result>/login.jsp/<result>

配置入口过滤器

<filter>

<filter-name>struts2/<filter-name>

<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter/<filter-class>

<filter-mapping>

<filter-name>struts2/<filter-name>

<url-pattern>/*/<url-pattern>

spring整合struts2

配置整合spring常量

<context-param>

<param-name>struts.objectFactory/<param-name>

<param-value>spring/<param-value>

方案1:Action对象仍然由struts2创建,spring负责组装依赖.

<context-param>

<param-name>struts.objectFactory.spring.autoWire/<param-name>

<param-value>name/<param-value>

在action中准备依赖属性

<bean>

方案2:Action对象创建与依赖注入全都由spring完成

将Action配置到spring容器中

<bean>

<property>

在Action配置中的class属性,填写对象的BeanName

<action>

<result>/login.jsp/<result>

搭建Hibernate框架

准备实体与映射文件

准备实体

映射文件 User.hbm.xml

<hibernate-mapping>

<class>

<generator>

<property>

<property>

<property>

准备主配置文件

在src目录下创建hibernate.cfg.xml

<hibernate-configuration>

<session-factory>

<mapping>

整合spring与hibernate

整合方式1:使用原生Hibernate配置文件

<bean>

<property>

整合方式2:将hibernate中的配置转移到spring中

<bean>

<property>

<props>

<prop>

<prop>

<property>

将c3p0连接池配置到spring

1.准备DB.properties

2.读取db.properties

<property-placeholder>

3.配置连接池对象,并注入连接配置

<bean>

<property><property>/<property>

<property><property>/<property>

<property><property>/<property>

<property><property>/<property>

4.将连接池对象注入到sessionFactory中

<bean>

<property>

<property>

<props>

<prop>

<prop>

<property>

将Dao&Hibernate模板配置到spring

书写Dao类

配置hibernate模板到spring

<bean>

<property>

配置dao到spring

<bean>

<property>

整合AOP事务

1.完成Service

<bean>

<property>

2.配置核心事务管理器

<bean>

<property>

XML|注解事务配置

xml配置

<advice>

<attributes>

<method>

<config>

<pointcut>

<advisor>

注解

<annotation-driven>

service中使用注解

@Transaction(progation=Progation.REQUIRED,readOnly=true,isolaction=Isolaction.REPEATABLE_READ)

publlic class UserServiceImpl implments UserService{

}

解决no-session问题

配置扩大session作用范围的过滤器

<filter>

<filter-name>OpenSessionInViewFilter/<filter-name>

<filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter/<filter-class>

<filter-mapping>

<filter-name>OpenSessionInViewFilter<filter-name>/<filter-name>

<url-pattern>/*/<url-pattern>