一、 需要的基础jar包
这里显示的是基础的jar包 , 后续你需要什么还应继续添加
MyEclipse可以一键导入自带的jar —–>项目名右键>MyEclipes>Add Spring……
二、 核心思想—>控制反转(依赖注入)
在项目中添加Spring的配置文件--->applicationContent.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
</beans>
比如我们想在B类的方法中实例化了A类的对象并调用其方法完成特定的功能这样的情况我们就可以说B类依赖A类;这样不利于降低代码之间的耦合度,利用Spring 我们可以实现控制反转,即在B类中不在依赖A类去获得具体的实例,而是把这个工作交给第三方,实现了控制反转.
更加利于实现面向接口编程, 只需要知道有这个接口,不需要在意这个接口是如何实现,降低代码耦合
这里有个简单的实体类 —>纸张类,如何使用Spring实现依赖注入呢?
在application中添加一段代码
<!-- id表示当前文件的唯一标示 class=""表示"<bean>"标签对应的类 -->
<bean id="A4" class="paper.TextPaper">
<!-- "property"对应类的属性 "name"表示对应哪个具体的属性 value是值 -->
<property name="lineCountChar" value="5"></property>
<property name="lineInPage" value="10"></property>
</bean>
利用下面的代码可以获取类型为 “paper.TextPaper”的对象和注入的对象的属性,实现控制反转
/*
*import org.springframework.context.ApplicationContext;
*import org.springframework.context.support.ClassPathXmlApplicationContext;
*/
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
TextPaper paper =(TextPaper) ac.getBean("A4");
如何注入复杂类型的数据呢?
例如 打印机类有墨盒类型和纸张类型的属性, 需要在 “bean”标签中如何配置呢
<!-- 配置纸张 -->
<bean id="A4" class="paper.TextPaper">
<property name="lineCountChar" value="5"></property>
<property name="lineInPage" value="10"></property>
</bean>
<!-- 配置打印机 -->
<bean id="print" class="entity.Printer">
<!-- 这里把value属性 换成ref 指向文件中配置好的一个纸张类 -->
<property name="paper" ref="A5"></property>
</bean>
这样就可以注入一个复杂类型的属性
二、 核心思想—>AOP(面向切面)
首先你需要导入AOP包,且要修改配置文件(application.xml)的头为:
以logger日志输出为例…..
1、新建日志输出类 LoggerAop
import java.util.Arrays;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
public class LoggerAop {
private Logger logger = Logger.getLogger(LoggerAop.class.getName());
public void before(JoinPoint jp) {
logger.info("before调用" + jp.getTarget().getClass().getName() + "的" +jp.getSignature().getName()+ "方法. 方法入参:" + Arrays.toString(jp.getArgs()));
}
public void afterReturning(JoinPoint jp,Object result) {
logger.info("afterReturning调用" + jp.getTarget().getClass().getName() + "的" + jp.getSignature().getName()
+ "方法. 方法返回值:" + result);
}
}
2、在配置文件(application.xml)添加 Aop 配置
<!-- 配置增强类 "class"属性对应增强类的地址 -->
<bean id="loggerAop" class="aop.LoggerAop"></bean>
<!-- 配置增强处理 -->
<aop:config>
<!-- 配置切入点 "expression"配置的是什么包下的什么类什么方法作为切入点-->
<!-- expression="execution(* com.service.*.*(..)) ----表示com.service包下所有类的所以方法 -->
<!-- expression="execution(* com.service..*.*(..)) ----表示com.service包及其子包下所有类的所以方法 -->
<aop:pointcut expression="execution(* inkBox..*.*(..))" id="pointcut" />
<!-- 引入增强类 -->
<aop:aspect ref="loggerAop">
<!-- 配置增强方法 切入点配置增强类的哪个方法-->
<!-- 前置增强 method表示引用增强类的哪个方法(方法名) -->
<!-- "pointcut-ref" 引入切入点 -->
<aop:before method="before" pointcut-ref="pointcut" />
<aop:after method="after" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
然后你在调用 inkBox包下的所有类的方法时会发生:
AOP(面向切面) 类似之前的过滤器 Filter—->相当于在你配置的切入点之前和之后做些什么事
增强类型:
1、 异常抛出增强
<!-- 发生异常时执行的增强 注意"throwing"指定的参数名称必须和 增强类中的异常参数一致! -->
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="ex"/>
<!-- 增强类中添加的方法 -->
public void afterThrowing(JoinPoint jp,Exception ex){
logger.info("afterThrowing"+ jp.getTarget().getClass().getName() + "的" + jp.getSignature().getName()+ex.getMessage());
}
2、 最终增强
<aop:after method="after" pointcut-ref="pointcut"/>
<!-- 特点:无论方法是抛出异常还是正常退出,该增强都会得到执行,一般用于释放资源 -->
3、 环绕增强
在目标方法的前后都可以织入增强处理,在环绕增强处理中,可以获取或修改目标方法的参数、返回值,可以进行异常处理,甚至可以决定目标方法是否被执行.
<!-- 添加环绕增强 -->
<aop:around method="around" pointcut-ref="pointcut"/>
<!-- 增强类添加的方法 -->
public Object around(ProceedingJoinPoint pjp) throws Throwable {
logger.info("调用" + pjp.getTarget().getClass().getName() + "的" + pjp.getSignature().getName()+"方法入参:"+Arrays.toString(pjp.getArgs()));
Object obj = null;
try {
// 让程序继续执行
// 此处的obj不接收对afterreturning没有影响
// 对程序中接受返回值有影响,所以要返回返回值
obj = pjp.proceed();
logger.debug(pjp.getTarget().getClass().getName() +"返回值是:" + obj);
return obj;
} catch (Throwable e) {
logger.error(pjp.getTarget().getClass().getName() +"方法发生异常:"+e.getMessage());
throw e;
}
finally{
logger.info(pjp.getTarget().getClass().getName() +"方法结束");
}
}
<!-- ProceedingJoinPoint 是 JoinPoint的子接口 -->
3、 after-returning增强
用于获得方法的返回值
<!-- returning指向的参数必须和增强方法中的参数一直 -->
<aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="result"/>
<!-- 添加增强方法 -->
public void afterReturning(JoinPoint jp,Object result) {
logger.info("afterReturning调用" + jp.getTarget().getClass().getName() + "的" + jp.getSignature().getName()
+ "方法. 方法返回值:" + result);
}