文章目录
一、Spring中XML和注解的选择问题
首先要明确:基于注解的 spring IoC 配置中,bean 对象的特点和基于 XML 配置是一模一样的
。
-
XML的优势
修改时,不用改源码,不涉及重新编译和部署。 -
注解的优势
配置简单,维护方便(我们找到类,就相当于找到了对应的配置) -
Spring 管理 Bean 方式的比较
基于XML的配置 | 基于注解配置 | |
---|---|---|
Bean定义 | <bean id="..." class="..." /> |
@Component(衍生类@Repository@Service@Controller) |
Bean名称 | 通过id或name指定 | @Component(“person”) |
Bean注入 | <property>或者通过p命名空间 |
@Autowired按类型注入@Qualifier按名称注入 |
生命过程、Bean作用范围 | init-method,destroy-method范围,scope属性 | @PostConstruct初始化@PreDestroy销毁@Scope设置作用范围 |
适用场景 | Bean来自第三方,使用它 | Bean的实现类由用户自己开发 |
二、注解配置AOP的步骤
(1)环境搭建
jar包可copy《XML配置AOP的步骤》
(2)在配置文件中导入Context的名称空间并指定要扫描的包
- 注意要开启 spring 对注解 AOP 的支持:
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd ">
<!-- 开启注解扫描 -->
<context:component-scan base-package="com.gql.aop,com.gql.transaction"></context:component-scan>
<!--开启 spring 对注解 AOP 的支持-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
(3)使用注解配置资源
以目标类为例
package com.gql.aop;
import org.springframework.stereotype.Component;
import com.gql.entity.Person;
/**
* 类说明:
* 目标类
* @guoqianliang1998.
*/
@Component("personDao")
public class PersonDaoImp implements PersonDao{
public void save(Person person) {
System.out.println("保存Person成功...");
}
}
(4)@Aspect声明切面类
@Aspect
- 作用:把当前类声明为切面类。
(5)使用注解配置通知
@Before前置通知
- 作用:把当前方法看成是前置通知。
- 属性:
value:用于指定切入点表达式,还可以指定切入点表达式的引用。
@AfterReturning后置通知
- 作用:把当前方法看成是后置通知。
- 属性:
value:用于指定切入点表达式,还可以指定切入点表达式的引用
@AfterThrowing异常通知
- 作用:把当前方法看成是异常通知。
- 属性:
value:用于指定切入点表达式,还可以指定切入点表达式的引用
@After最终通知
- 作用:把当前方法看成是最终通知。
- 属性:
value:用于指定切入点表达式,还可以指定切入点表达式的引用
@Around环绕通知
- 作用:把当前方法看成是环绕通知。
- 属性:
value:用于指定切入点表达式,还可以指定切入点表达式的引用。
(6)切入点表达式注解
@Pointcut
- 作用:指定切入点表达式。
- 属性:
value:指定表达式的内容。
package com.gql.transaction;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
* 类说明:
* 事务类
* @guoqianliang1998.
*/
@Component("m")
@Aspect
public class MyTransaction {
//切入点
@Pointcut("execution (* com.gql.aop.PersonDaoImp.*(..))")
public void point(){}
@Before("point()")
public void begin(){
System.out.println("开启事务...");
}
@AfterReturning("point()")
public void commit(){
System.out.println("提交事务...");
}
//@AfterThrowing
public void ex(Throwable e){
System.out.println(e.getMessage());
System.out.println("出现异常...");
}
//@After
public void finall(){
System.out.println("最终通知...");
}
//@Around
public void around(ProceedingJoinPoint p ) throws Throwable{
System.out.println("环绕通知前...");
p.proceed();//放行,执行目标方法
System.out.println("环绕通知后...");
}
}
(7)测试类
@Test
public void test1(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext_annotation.xml");
PersonDao personDao = (PersonDao) ac.getBean("personDao");
personDao.save(new Person());
}