1.Spring是什么?
一个轻量级的开源框架,是一个 IOC(DI) 和 AOP 容器框架,
IOC:inversion of control (反转控制)翻转资源的获取的方向
容器主动的将资源推送给他所管理的组件,组件所要做的仅是选择一种合适的方式来接受资源。这种行为也被成为查找的被动形式
DI:Dependency Injection (依赖注入) IOC的另一种表示方式
组件一些预先定义好的方式(例如:setter方法)接受来自 如 容器的资源注入,相对于IOC而言,这种表述更直接
AOP : aspect oriented programming 面向切面编程
容器:Spring 是一个容器, 因为它包含并且管理应用对象的生命周期
框架:Spring 实现了使用简单的组件配置组合成一个复杂的应用. 在 Spring 中可以使用 XML 和 Java 注解组合这些对象
2.怎么建立Spring
public class Main {
public static void main(String[] args){
// 1.创建Spring的IOC容器对象
// ApplicationContext 代表 IOC容器
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2.从IOC容器中获取Bean实例
HelloWorld hw = (HelloWorld)ac.getBean("helloWorld");
// 3.调用hello方法
hw.hello();
}
3.Spring生命周期
IOC 容器中 Bean 的生命周期方法
在 Bean 生命周期的特定点执行定制的任务.
Spring IOC 容器对 Bean 的生命周期进行管理的过程:
1.通过构造器或工厂方法创建 Bean 实例
2.为 Bean 的属性设置值和对其他 Bean 的引用
3.调用 Bean 的初始化方法
4.Bean 可以使用了
5.当容器关闭时, 调用 Bean 的销毁方法
在 Bean 的声明里设置 init-method 和 destroy-method 属性, 为 Bean 指定初始化和销毁方法.
4.面向切面编程
AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面向对象编程) 的补充.
AspectJ:Java 社区里最完整最流行的 AOP 框架.
在 Spring2.0 以上版本中, 可以使用基于 AspectJ 注解或基于 XML 配置的 AOP
--->在 Spring 中启用 AspectJ 注解支持AOP
要在 Spring 应用中使用 AspectJ 注解, 必须在 classpath 下包含 AspectJ 类库: aopalliance.jar、aspectj.weaver.jar 和 spring-aspects.jar
将 aop Schema 添加到 <beans> 根元素中.
要在 Spring IOC 容器中启用 AspectJ 注解支持, 只要在 Bean 配置文件中定义一个空的 XML 元素 <aop:aspectj-autoproxy>
当 Spring IOC 容器侦测到 Bean 配置文件中的 <aop:aspectj-autoproxy> 元素时, 会自动为与 AspectJ 切面匹配的 Bean 创建代理.
AspectJ支持的5种类型的通知注解
try{
//前置通知
result = method.invoke(target,args)
//返回通知,可以访问到方法的返回值
} catch (Exception ex){
e,printStackTrace();
//异常通知,可以访问到方法出现的异常
}
//后置通知,因为方法可能出异常,所以访问不到方法的返回值
环绕通知:前几个通知的总结
/*
* 环绕通知需要携带 ProceedingJoinPoint 类型的参数
* 类似乎动态代理的全过程: ProceedingJoinPoint类型的参数可以决定是否执行目标方法
* 必须要有返回值,返回值即为目标方法的返回值
*/
@Around("execution(* cn.junhui.bean.aop.impl.Calculator.*(..))")
public Object aroundMethod(ProceedingJoinPoint pjp) {
Object result = null;
String methodName = pjp.getSignature().getName();
try {
//前置通知
System.out.println("Before: the method " + methodName + "begins with " + Arrays.asList(pjp.getArgs()));
result = pjp.proceed();
//返回通知
System.out.println("AfterReturning: the method " + methodName + "result");
} catch (Throwable e) {
e.printStackTrace();
//异常通知
System.out.println("AfterThrowing: the method " + methodName + "occurs exception:" + e);
}
//后置通知
System.out.println("After: the method " + methodName + "ends");
return result;
}
/*
* 定义一个方法,用于声明切入点表达式,
* 一般地,该方法中不需要填入其他的代码
* 使用@Pointcut声明切入点
* 此后调用此方法即可
*/
@Pointcut("execution(* cn.junhui.bean.aop.impl.*.*(int,int))")
public void declareJointPointExpression() {}
例子如下:
//声明该方法是一个前置通知:在目标方法开始之前执行
@Before("declareJointPointExpression()")
public void beforeMethod(JoinPoint jp) {}
--->在 Spring 中基于配置文件来配置AOP
<!-- 配置bean -->
<bean id = "carculator" class="cn.junhui.bean.aop.xml.CalculatorImpl">
</bean>
<!-- 配置切面的bean -->
<bean id = "logging" class="cn.junhui.bean.aop.xml.LoggingAspect">
</bean>
<bean id="vlidation" class="cn.junhui.bean.aop.xml.VlidationAspect">
</bean>
<!-- 配置AOP -->
<aop:config>
<!-- 配置切点表达式 -->
<aop:pointcut expression="execution(* cn.junhui.bean.aop.xml.*.*(int,int))"
id="pointcut"/>
<!-- 配置切面及通知 -->
<aop:aspect ref="logging" order="2">
<aop:before method="beforeMethod" pointcut-ref="pointcut"/>
<aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="result"/>
<aop:after-throwing method="AfterThrowing" pointcut-ref="pointcut" throwing="ex"/>
<aop:after method="afterMethod" pointcut-ref="pointcut"/>
</aop:aspect>
<aop:aspect ref="vlidation" order="1">
<aop:before method="validateArgs" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>