Spring容器AOP,IOC,ID全部知识点

Spring是一个从实际开发中抽取出来的框架,因此它完成了大量开发中通用步骤,留给开发者的仅仅是与特定应用相关的部分,从而大大提高企业应用开发效率。
Spring提供了一种Template的设计哲学,这些Template完成了大量的通用步骤,如果开发者使用这些Template,则无须自己实现那些通用步骤。
Spring我企业应用的开发提供了一个轻量级的解决方案,改解决方案包括:基于依赖注入的核心机制,基于AOP的声明式事务管理,与多种持久层技术的整合,以及优秀的WebMVC框架等。Spring贯穿表现层,业务层,持久层,然后,Spring并不想取代那些已有的框架,而是以高度的开放性与他们无缝整合。
总结起来Spring具有如下优点:
低入侵是设计,代码的污染极低
独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once、Run Anywhere 的承诺。
Spring的DI容器降低了业务对象替换的复杂性,提高了组件之间的解耦
Spring的AOP支持允许将一些任务如安全、事务、日志等进行集中式处理,从而提供了更好的复用。
Spring的ORM和DAO提供了与第三方持久层框架的良好整合,并简化了底层的数据库访问。
Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部。

当我们使用Spring框架是,必须使用Spring Core Container(即Spring容器)、他代表了Spring框架的核心机制,Spring Core Container 主要有 org.springframework.core、org.springframework.beans和org.springframework.context、org.springframework.expression四个包及其子包是Spring3.0新增的,他提供了Spring Expression Language支持.

IOC:控制反转:将对象的创建权,由Spring管理.
DI:依赖注入:在Spring创建对象的过程中,把对象依赖的属性注入到类中.

  • 面向对象中对象之间的关系;
  • 依赖:
    public class A{
    private B b;
    }
  • 继承:is a
  • 聚合:
  • 聚集:
  • 组合:

Spring框架加载配置文件
ApplicationContext 应用上下文,加载Spring 框架配置文件
加载classpath:
new ClassPathXmlApplicationContext(“applicationContext.xml”); :加载classpath下面配置文件.
加载磁盘路径:
new FileSystemXmlApplicationContext(“applicationContext.xml”); :加载磁盘下配置文件.

BeanFactory与ApplicationContext区别?
ApplicationContext类继承了BeanFactory.
BeanFactory在使用到这个类的时候,getBean()方法的时候才会加载这个类.
ApplicationContext类加载配置文件的时候,创建所有的类.
ApplicationContext对BeanFactory提供了扩展:

  • 国际化处理
  • 事件传递
  • Bean自动装配
  • 各种不同应用层的Context实现
    ***** 早期开发使用BeanFactory.

Bean的其他配置:
id和name的区别:
id遵守XML约束的id的约束.id约束保证这个属性的值是唯一的,而且必须以字母开始,可以使用字母、数字、连字符、下划线、句话、冒号
name没有这些要求
***** 如果bean标签上没有配置id,那么name可以作为id.
***** 开发中Spring和Struts1整合的时候, /login.

现在的开发中都使用id属性即可

类的作用范围:
scope属性 :

  • singleton :单例的.(默认的值.)
  • prototype :多例的.
  • request :web开发中.创建了一个对象,将这个对象存入request范围,request.setAttribute();
  • session :web开发中.创建了一个对象,将这个对象存入session范围,session.setAttribute();
  • globalSession :一般用于Porlet应用环境.指的是分布式开发.不是porlet环境,globalSession等同于session;
    实际开发中主要使用singleton,prototype.

Bean的生命周期:
配置Bean的初始化和销毁的方法:
配置初始化和销毁的方法:

  • init-method=”setup”
  • destroy-method=”teardown”
    执行销毁的时候,必须手动关闭工厂,而且只对scope=”singleton”有效.

Bean的生命周期的11个步骤:
1.instantiate bean对象实例化
2.populate properties 封装属性
3.如果Bean实现BeanNameAware 执行 setBeanName
4.如果Bean实现BeanFactoryAware 或者 ApplicationContextAware 设置工厂 setBeanFactory 或者上下文对象 setApplicationContext
5.如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessBeforeInitialization
6.如果Bean实现InitializingBean 执行 afterPropertiesSet
7.调用 指定初始化方法 init
8.如果存在类实现 BeanPostProcessor(处理Bean) ,执行postProcessAfterInitialization
9.执行业务处理
10.如果Bean实现 DisposableBean 执行 destroy
11.调用 指定销毁方法 customerDestroy
在CustomerService类的add方法之前进行权限校验?

Bean中属性注入:
Spring支持构造方法注入和setter方法注入:
构造器注入:

setter方法注入: setter方法注入对象属性: 集合属性的注入: 童童 小凤 杜宏 如花 root 123 加载配置文件: 一种写法: ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean1.xml",”bean2.xml”); 二种方法: Spring的注解装配Bean Spring2.5 引入使用注解去定义Bean @Component 描述Spring框架中Bean

Spring的框架中提供了与@Component注解等效的三个注解:
@Repository 用于对DAO实现类进行标注
@Service 用于对Service实现类进行标注
@Controller 用于对Controller实现类进行标注
***** 三个注解为了后续版本进行增强的.
依赖注入
使用依赖注入,不仅可以为Bean注入普通的属性值,还可以注入其他bean的引用。通过这种依赖注入,Java EE 应用中的各种组件不需要以硬编码方式耦合在一起,甚至无需使用工程模式。依赖注入达到的效果,非常类似于传说中的共产主义,当某个Java实例需要其他Java实例时,系统自动提供所需要的实例,无需程序显示获取。
Spring注解
映射类声明变量前,加入此注解页面将数据传到后台,是以字符串的形式。所以时间格式会出错
@DateTimeFormat(pattern = “yyyy-MM-dd HH:mm:ss” )

Bean的属性注入:
普通属性;
@Value(value=“itcast”)
private String info;

对象属性:
@Autowired:自动装配默认使用类型注入.
@Autowired
@Qualifier(“userDao”) — 按名称进行注入.

@Autowired
@Qualifier(“userDao”)
private UserDao userDao;
等价于
@Resource(name=“userDao”)
private UserDao userDao;
Bean其他的属性的配置:
配置Bean初始化方法和销毁方法:
init-method 和 destroy-method.
@PostConstruct 初始化
@PreDestroy 销毁

配置Bean的作用范围:
@Scope
Spring3.0提供使用Java类定义Bean信息的方法
@Configuration
public class BeanConfig {

@Bean(name=“car”)
public Car showCar(){
Car car = new Car();
car.setName(“长安”);
car.setPrice(40000d);
return car;
}
@Bean(name=“product”)
public Product initProduct(){
Product product = new Product();
product.setName(“空调”);
product.setPrice(3000d);
return product;
}
}
实际开发中使用XML还是注解?
XML:

  • bean管理
    注解;
  • 注入属性的时候比较方便.

两种方式结合;一般使用XML注册Bean,使用注解进行属性的注入.

context:annotation-config/
s
@Autowired
@Qualifier(“orderDao”)
private OrderDao orderDao;

Spring整合web开发:
正常整合Servlet和Spring没有问题的
但是每次执行Servlet的时候加载Spring配置,加载Spring环境.

  • 解决办法:在Servlet的init方法中加载Spring配置文件?
  • 当前这个Servlet可以使用,但是其他的Servlet的用不了了!!!
  • 将加载的信息内容放到ServletContext中.ServletContext对象时全局的对象.服务器启动的时候创建的.在创建ServletContext的时候就加载Spring的环境.
  • ServletContextListener:用于监听ServletContext对象的创建和销毁的.
    导入;spring-web-3.2.0.RELEASE.jar
    在web.xml中配置:

    org.springframework.web.context.ContextLoaderListener
contextConfigLocation classpath:applicationContext.xml 修改程序的代码: WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); WebApplicationContext applicationContext = (WebApplicationContext) getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);

什么是AOP:
AOP Aspect Oriented Programing 面向切面编程
AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)
Spring AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码
AspecJ是一个基于Java语言的AOP框架,Spring2.0开始,Spring AOP引入对Aspect的支持,AspectJ扩展了Java语言,提供了一个专门的编译器,在编译时提供横向代码的织入

AOP底层原理;
就是代理机制:

  • 动态代理:(JDK中使用)
  • JDK的动态代理,对实现了接口的类生成代理.

Spring的AOP代理:
JDK动态代理:对实现了接口的类生成代理
CGLib代理机制:对类生成代理

AOP的术语:
Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点.
Pointcut(切入点):所谓切入点是指我们要对哪些Joinpoint进行拦截的定义.
Advice(通知/增强):所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)
Introduction(引介):引介是一种特殊的通知在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field.
Target(目标对象):代理的目标对象
Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程.
spring采用动态代理织入,而AspectJ采用编译期织入和类装在期织入
Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类
Aspect(切面): 是切入点和通知(引介)的结合

JDK动态代理:
public class JDKProxy implements InvocationHandler

CGLIB动态代理:
CGLIB(Code Generation Library)是一个开源项 目!是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。 Hibernate支持它来实现PO(Persistent Object 持久化对象)字节码的动态生成
Hibernate生成持久化类的javassist.
CGLIB生成代理机制:其实生成了一个真实对象的子类.

结论:Spring框架,如果类实现了接口,就使用JDK的动态代理生成代理对象,如果这个类没有实现任何接口,使用CGLIB生成代理对象.

Spring的传统AOP :
AOP:不是由Spring定义.AOP联盟的组织定义.
Spring中的通知:(增强代码)
前置通知 org.springframework.aop.MethodBeforeAdvice

  • 在目标方法执行前实施增强
    后置通知 org.springframework.aop.AfterReturningAdvice
  • 在目标方法执行后实施增强
    环绕通知 org.aopalliance.intercept.MethodInterceptor
  • 在目标方法执行前后实施增强
    异常抛出通知 org.springframework.aop.ThrowsAdvice
  • 在方法抛出异常后实施增强
    引介通知 org.springframework.aop.IntroductionInterceptor(课程不讲.)
  • 在目标类中添加一些新的方法和属性

Spring中的切面类型:
Advisor : Spring中传统切面.

  • Advisor:都是有一个切点和一个通知组合.
  • Aspect:多个切点和多个通知组合.

Advisor : 代表一般切面,Advice本身就是一个切面,对目标类所有方法进行拦截(* 不带有切点的切面.针对所有方法进行拦截)
PointcutAdvisor : 代表具有切点的切面,可以指定拦截目标类哪些方法(带有切点的切面,针对某个方法进行拦截)
IntroductionAdvisor : 代表引介切面,针对引介通知而使用切面(不要求掌握)

带有切点的切面:(针对目标对象的某些方法进行增强)
PointcutAdvisor 接口:
DefaultPointcutAdvisor 最常用的切面类型,它可以通过任意Pointcut和Advice 组合定义切面
RegexpMethodPointcutAdvisor 构造正则表达式切点切面

自动代理:
前面的案例中,每个代理都是通过ProxyFactoryBean织入切面代理,在实际开发中,非常多的Bean每个都配置ProxyFactoryBean开发维护量巨大

自动创建代理(*****基于后处理Bean.在Bean创建的过程中完成的增强.生成Bean就是代理.)
BeanNameAutoProxyCreator 根据Bean名称创建代理
DefaultAdvisorAutoProxyCreator 根据Advisor本身包含信息创建代理

  • AnnotationAwareAspectJAutoProxyCreator 基于Bean中的AspectJ 注解进行自动代理

Spring的AspectJ的AOP(*****)
AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。
AspectJ是一个基于Java语言的AOP框架
Spring2.0以后新增了对AspectJ切点表达式支持
@AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面
新版本Spring框架,建议使用AspectJ方式来开发AOP

AspectJ表达式:

  • 语法:execution(表达式)
    execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)

  • execution(“* cn.itcast.spring3.demo1.dao.*(…)”) —只检索当前包

  • execution(“* cn.itcast.spring3.demo1.dao…*(…)”) —检索包及当前包的子包.

  • execution(* cn.itcast.dao.GenericDAO+.*(…)) —检索GenericDAO及子类

AspectJ增强:
@Before 前置通知,相当于BeforeAdvice
@AfterReturning 后置通知,相当于AfterReturningAdvice
@Around 环绕通知,相当于MethodInterceptor
@AfterThrowing抛出通知,相当于ThrowAdvice
@After 最终final通知,不管是否异常,该通知都会执行
@DeclareParents 引介通知,相当于IntroductionInterceptor (不要求掌握)

基于注解:
第一步:引入相应jar包.

  • aspectj依赖aop环境.
  • spring-aspects-3.2.0.RELEASE.jar
  • com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

第二步:编写被增强的类:

  • UserDao

第三步:使用AspectJ注解形式:
@Aspect
public class MyAspect {
@Before(“execution(* cn.itcast.spring3.demo1.UserDao.add(…))”)
public void before(){
System.out.println(“前置增强…”);
}
}

第四步:创建applicationContext.xml

  • 引入aop的约束:
  • <aop:aspectj-autoproxy /> — 自动生成代理:
  • 底层就是AnnotationAwareAspectJAutoProxyCreator

<aop:aspectj-autoproxy />

Spring的JdbcTemplate
Spring对持久层技术支持:
JDBC : org.springframework.jdbc.core.JdbcTemplate
Hibernate3.0 : org.springframework.orm.hibernate3.HibernateTemplate
IBatis(MyBatis) : org.springframework.orm.ibatis.SqlMapClientTemplate
JPA : org.springframework.orm.jpa.JpaTemplate
Spring默认的连接池:

DBCP连接池: 导入jar包: * com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jar * com.springsource.org.apache.commons.pool-1.5.3.jar C3P0连接池: 导入jar包: * com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar

参数设置到属性文件中:
在src下创建jdbc.properties
jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql:///spring3_day02
jdbc.user = root
jdbc.password = 123

需要在applicationContext.xml 中使用属性文件配置的内容.

  • 第一种写法:


  • 第二种写法:
    <context:property-placeholder location=“classpath:jdbc.properties”/>

JdbcTemplate的CRUD的操作:
Spring框架中提供了对持久层技术支持的类:
JDBC : org.springframework.jdbc.core.support.JdbcDaoSupport
Hibernate 3.0 : org.springframework.orm.hibernate3.support.HibernateDaoSupport
iBatis : org.springframework.orm.ibatis.support.SqlMapClientDaoSupport

Spring的事务管理:
事务:
事务:是逻辑上一组操作,要么全都成功,要么全都失败.
事务特性:
ACID:
原子性:事务不可分割
一致性:事务执行的前后,数据完整性保持一致.
隔离性:一个事务执行的时候,不应该受到其他事务的打扰
持久性:一旦结束,数据就永久的保存到数据库.

如果不考虑隔离性:
脏读:一个事务读到另一个事务未提交数据
不可重复读:一个事务读到另一个事务已经提交数据(update)导致一个事务多次查询结果不一致
虚读:一个事务读到另一个事务已经提交数据(insert)导致一个事务多次查询结果不一致

事务的隔离级别:
未提交读:以上情况都有可能发生。
已提交读:避免脏读,但不可重复读,虚读是有可能发生。
可重复读:避免脏读,不可重复读,但是虚读有可能发生。
串行的:避免以上所有情况.

Spring中事务管理:
分层开发:事务处在Service层.

Spring提供事务管理API:
PlatformTransactionManager:平台事务管理器.
commit(TransactionStatus status)
getTransaction(TransactionDefinition definition)
rollback(TransactionStatus status)

TransactionDefinition:事务定义
ISOLation_XXX:事务隔离级别.
PROPAGATION_XXX:事务的传播行为.(不是JDBC中有的,为了解决实际开发问题.)
过期时间:

TransactionStatus:事务状态
是否有保存点
是否一个新的事务
事务是否已经提交

关系:PlatformTransactionManager通过TransactionDefinition设置事务相关信息管理事务,管理事务过程中,产生一些事务状态:状态由TransactionStatus记录.

API详解:
PlatformTransactionManager:接口.
Spring为不同的持久化框架提供了不同PlatformTransactionManager接口实现

org.springframework.jdbc.datasource.DataSourceTransactionManager : 使用Spring JDBC或iBatis 进行持久化数据时使用
org.springframework.orm.hibernate3.HibernateTransactionManager : 使用Hibernate3.0版本进行持久化数据时使用
org.springframework.orm.jpa.JpaTransactionManager 使用JPA进行持久化时使用
org.springframework.jdo.JdoTransactionManager 当持久化机制是Jdo时使用
org.springframework.transaction.jta.JtaTransactionManager 使用一个JTA实现来管理事务,在一个事务跨越多个资源时必须使用

TransactionDefinition:

  • ISOLATION_DEFAULT:默认级别. Mysql repeatable_read oracle read_commited

Spring的事务管理:
手动编码的方式完成事务管理:
需要事务管理器:真正管理事务对象.

  • Spring提供了事务管理的模板(工具类.)

第一步:注册事务管理器:

第二步:注册事务模板类:

第三步:在业务层注入模板类:(模板类管理事务)

第四步:在业务层代码上使用模板:
public void transfer(final String from, final String to, final Double money) {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
accountDao.out(from, money);
int d = 1 / 0;
accountDao.in(to, money);
}
});
}

手动编码方式缺点:

  • 代码量增加,代码有侵入性.

声明式事务管理:(原始方式)
基于TransactionProxyFactoryBean.
导入:aop相应jar包.

第一步:注册平台事务管理器:

第二步:创建业务层代理对象:

PROPAGATION_REQUIRED

第三步:编写测试类:
***** 千万注意:注入代理对象
@Autowired
@Qualifier(“accountServiceProxy”)
private AccountService accountService;

prop格式:PROPAGATION,ISOLATION,readOnly,-Exception,+Exception

  • 顺序:传播行为、隔离级别、事务是否只读、发生哪些异常可以回滚事务(所有的异常都回滚)、发生了哪些异常不回滚.

***** 缺点:就是需要为每一个管理事务的类生成代理.需要为每个类都需要进行配置.

声明式事务管理:(自动代理.基于切面 ******)
第一步:导入相应jar包.

第三步:注册事务管理器;

第四步:定义增强(事务管理)

<tx:advice id=“txAdvice” transaction-manager=“transactionManager”>

tx:attributes

<tx:method name=“transfer”/>
</tx:attributes>
</tx:advice>

第五步:定义aop的配置(切点和通知的组合)

aop:config

<aop:pointcut expression=“execution(* cn.itcast.spring3.demo3.AccountService+.*(…))” id=“mypointcut”/>

<aop:advisor advice-ref=“txAdvice” pointcut-ref=“mypointcut”/>
</aop:config>

第六步:编写测试类:

  • 注入Service对象,不需要注入代理对象(生成这个类的时候,已经是代理对象.)
    基于注解的事务管理:
    引入aop和tx命名空间
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值