Spring——注解开发、Junit4注解测试、SpringAOP
本次学习需要的jar包
分层开发的xml文件配置
单xml文件配置
<bean id="StudentDao" class="com.dao.StudentDaoImpl">
</bean>
<bean id="StudentService" class="com.service.StudentServiceImpl">
<property name="dao" ref="StudentDao"></property>
</bean>
<bean id="StudentServlet" class="com.controller.StudentServlet">
<property name="service" ref="StudentService"></property>
</bean>
注意: 每个被注入的类中要写get()和set()方法
多xml文件配置
<!--导入另外两个xml文件-->
<import resource="applicationContextService.xml"></import>
<import resource="applicationContextDao.xml"></import>
<bean id="StudentServlet" class="com.controller.StudentServlet">
<property name="service" ref="StudentService"></property>
</bean>
注解开发
注解扫描需要引入Context的schema命名空间
xmlns:context="http://www.springframework.org/schema/context"
schemaLocation:
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
注解
注解 | 说明 |
---|---|
@Component | 使用在类上用于实例化Bean |
@Controller | 使用在Controller层类上用于实例化Bean |
@Service | 使用在service层类上用于实例化Bean |
@Repository | 使用在dao层类上用于实例化Bean |
@Autowired | 使用在字段上用于根据类型依赖注入 |
@Qualifier | 结合@Autowired一起使用用于根据名称进行依赖注入 |
@Resource | 相当于@Autowired+@Qualifier,按照名称进行注入 |
@Value | 注入普通属性 |
@Scope | 标注Bean的作用范围 |
@PostConstruct | 使用在方法上标注该方法是Bean的初始化方法 |
@PreDestroy | 使用在方法上标注该方法是Bean的销毁方法 |
例如:
@Controller
public class StudentServlet {
@Autowired
private StudentService service;
public StudentService getService() {
return service;
}
public void setService(StudentService service) {
this.service = service;
}
public void getMsg(){
service.getMsg();
}
}
xml配置文件
<!--Spring扫描指定com包,进行注解解析-->
<context:component-scan base-package="com"></context:component-scan>
测试类
public static void main(String[] args) {
ApplicationContext c = new ClassPathXmlApplicationContext("applicationContext.xml");
//采用注解开发时,getBean()中为引用类名,但首字母要小写
StudentServlet s = (StudentServlet) c.getBean("studentServlet");
//使用名称
StudentServlet s = (StudentServlet) c.getBean("servlet");
s.getMsg();
}
按照名称注解
@Repository("dao2")//设置名称
public class StudentDaoImpl2 implements StudentDao{
@Override
public void getMsg() {
System.out.println("使用名称注解");
}
}
@Autowired
@Qualifier("dao2")
private StudentDao dao;
//或者
@Resource(name = "dao2")
private StudentDao dao;
注意: 采用注解开发时,getBean()中为引用类名或者注解名称,默认类名。但首字母要小写
SpringJunit4-注解测试
首先导入需要的jar包
将Junit4添加到编译路径(classpath)中
注解测试
//创建Spring容器
@RunWith(SpringJUnit4ClassRunner.class)
//指定配置文件路径
@ContextConfiguration("classpath:applicationContext.xml")
public class Test1 {
@Resource
private StudentServlet ss;
//测试方法
@Test
public void test1(){
ss.getMsg();
}
}
SpringAOP
1、 AOP
AOP 为 Aspect Oriented Programming 的缩写,意思为面向切面编程,是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
AOP 是 OOP 的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
2 、AOP 的作用及其优势
作用:在程序运行期间,在不修改源码的情况下对方法进行功能增强
优势:减少重复代码,提高开发效率,并且便于维护
3 、AOP 的底层实现
AOP 的底层是通过 Spring 提供的的动态代理技术实现的。在运行期间,Spring通过动态代理技术动态的生成代理对象,代理对象方法执行时进行增强功能的介入,在去调用目标对象的方法,从而完成功能的增强。
4、 AOP 相关概念
Spring 的 AOP 实现底层就是对上面的动态代理的代码进行了封装,封装后我们只需要对需要关注的部分进行代码编写,并通过配置的方式完成指定目标的方法增强。
Target(目标对象) | 代理的目标对象 |
Proxy (代理) | 一个类被 AOP 织入增强后,就产生一个结果代理类 |
Joinpoint(连接点) | 所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点 |
Pointcut(切入点) | 所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义 |
Advice(通知/ 增强) | 所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知 |
Aspect(切面) | 是切入点和通知(引介)的结合 |
Weaving(织入) | 是指把增强应用到目标对象来创建新的代理对象的过程。spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入 |
1、配置AOP命名空间和Jar包
jar包
配置AOP命名空间
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
2、创建 通知 myAdvice(增强)
// 通知/增强类
public class MyAdvice {
public void before(){
System.out.println("前置通知");
}
public void after(){
System.out.println("后置通知(出现异常也会执行)");
}
public Object around(ProceedingJoinPoint jp) throws Throwable {
System.out.println("环绕通知 前");
Object value = jp.proceed();//调用目标对象原本的方法
System.out.println("环绕通知 后");
return value;
}
public void afterThrowing(){
System.out.println("异常通知:只会在方法执行异常的时候才执行");
}
public void afterReturning(){
System.out.println("后置通知(出现异常不执行)");
}
}
3、创建目标对象(切入点)
//目标对象
@Service
public class StudentServiceImpl implements StudentService{
//切入点(方法)
@Override
public void add() {
System.out.println("数据库操作--add");
}
@Override
public void delete() {
System.out.println("数据库操作--delete");
}
@Override
public void update() {
System.out.println("数据库操作--update");
}
@Override
public void select() {
System.out.println("数据库操作--select");
}
}
AOPxml配置
4、xml配置通知(增强)
<!--配置增强(通知)类实例化对象-->
<bean id="myAdvice" class="com.advice.MyAdvice"></bean>
5、xml配置AOP中的切入点(写在< aop:config >中)
<!--配置切入点-->
<!--
public void com.Service.StudentServiceImpl.add(..)
* com.Service.*ServiceImpl.*(..)
-->
<aop:pointcut id="pc" expression="execution(* com.Service.*ServiceImpl.*(..))"/>
6、xml配置切面 :将 ‘通知’ 织入 ‘切入点’ ——>切面
通知 + 切入点 = 切面
<!--
配置切面:将 “”'通知' 织入 '切入点'
通知 + 切入点 = 切面
-->
<aop:aspect ref="myAdvice">
<aop:before method="before" pointcut-ref="pc"></aop:before>
<aop:after method="after" pointcut-ref="pc"></aop:after>
<aop:around method="around" pointcut-ref="pc"></aop:around>
<aop:after-throwing method="afterThrowing" pointcut-ref="pc"></aop:after-throwing>
<aop:after-returning method="afterReturning" pointcut-ref="pc"></aop:after-returning>
</aop:aspect>
完整代码:
<!--Spring扫描指定com包,进行注解解析-->
<context:component-scan base-package="com"></context:component-scan>
<!--配置增强(通知)类实例化对象-->
<bean id="myAdvice" class="com.advice.MyAdvice"></bean>
<!--配置AOP-->
<aop:config>
<!--配置切入点-->
<!--
public void com.Service.StudentServiceImpl.add(..)
* com.Service.*ServiceImpl.*(..)
-->
<aop:pointcut id="pc" expression="execution(* com.Service.*ServiceImpl.*(..))"/>
<!--
配置切面:将 “”'通知' 织入 '切入点'
通知 + 切入点 = 切面
-->
<aop:aspect ref="myAdvice">
<aop:before method="before" pointcut-ref="pc"></aop:before>
<aop:after method="after" pointcut-ref="pc"></aop:after>
<aop:around method="around" pointcut-ref="pc"></aop:around>
<aop:after-throwing method="afterThrowing" pointcut-ref="pc"></aop:after-throwing>
<aop:after-returning method="afterReturning" pointcut-ref="pc"></aop:after-returning>
</aop:aspect>
</aop:config>
AOP注解配置
注解 通知(增强)类
注解配置
测试类:
//创建Spring容器
@RunWith(SpringJUnit4ClassRunner.class)
//引入配置文件
@ContextConfiguration("classpath:applicationContext.xml")
public class Test1 {
@Resource
private StudentService ss;
@Test
public void test(){
ss.add();
}
}
运行结果