IoC Annotation Based | |
标注组件的注解 | @org.springframework.stereotype.Repository 专门用于标注数据访问组件 @org.springframework.stereotype.Service 专门用于标注业务组件 @org.springframework.stereotype.Controller 专门用于标注控制器组件 @org.springframework.stereotype.Component 可以标注任意类型组件 |
标注作用域的注解 | @org.springframework.context.annotation.Scope singleton prototype request session |
实现自动装配的注解 | @org.springframework.beans.factory.annotation.Autowired 用于实现自动装配 可以标注在需要自动装配的字段上,也可以是该字段对应的 setter 上 默认根据类型进行自动装配 @org.springframework.beans.factory.annotation.Qualifier 配合 Autowired 实现按照名称自动装配 配合 Autowired 可以标注在需要自动装配的字段上,也可以是该字段对应的 setter 上 |
AOP Annotation Based | |
标注切面类的注解 | @org.aspectj.lang.annotation.Aspect |
表示方位的注解 | @org.aspectj.lang.annotation.Before @org.aspectj.lang.annotation.Around @org.aspectj.lang.annotation.AfterReturning @org.aspectj.lang.annotation.AfterThrowing @org.aspectj.lang.annotation.After |
标注切点 | @org.aspectj.lang.annotation.Pointcut |
表示织入顺序 | @org.springframework.core.annotation.Order |
AOP的注解版
1.创建一个Student类,声明两个字段id,name
public class Student {
private Integer id ; // object identifier filed
private String name ; // student name
}
2.创建一个StudentDao类,用于被数据访问,作用域为singleton
// <bean id="studentDao" class="com.itlaobing.aop.annotation.dao.StudentDao" scope="singleton" />
@Repository//标注组件的注解//专门用于标注数据访问组件
@Scope( "singleton" )//标注作用域为singleton的注解
public class StudentDao {
public void persist(Student s ) {
System.out.println( "保存 { id : " + s.getId() + ", name : " + s.getName() + " }" );
}
}
3.创建一个StudentService类
// <bean id="studentService" class="com.itlaobing.aop.annotation.service.StudentService" scope="singleton" />
@Service( "studentService" )//标注组件的注解//专门用于标注业务组件
public class StudentService {
@Autowired
//用于实现自动装配//可以标注在需要自动装配的字段上,也可以是该字段对应的 setter 上//默认根据类型进行自动装配
private StudentDao studentDao ; // field
public void save( Student s ) {
System.out.println( "[ StudentService ] - [ save( Student ) ]" );
studentDao.persist( s );
}
public StudentDao getStudentDao() {
return studentDao;
}
public void setStudentDao(StudentDao studentDao) {
System.out.println( "[ StudentService ] - [ setStudentDao ]" );
this.studentDao = studentDao;
}
}
4.创建一个StudentController类
// <bean id="studentController" class="com.itlaobing.aop.annotation.controller.StudentController" scope="singleton" />
@Controller//专门用于标注控制器组件
public class StudentController {
private StudentService studentService ;
public void signUp(Student s ) {
studentService.save( s );
}
public StudentService getStudentService() {
return studentService;
}
//用于实现自动装配
// 可以标注在需要自动装配的字段上,也可以是该字段对应的 setter 上
// 默认根据类型进行自动装配
@Autowired
//配合 Autowired 实现按照名称自动装配
//配合 Autowired 可以标注在需要自动装配的字段上,也可以是该字段对应的 setter 上
@Qualifier( "studentService" )
public void setStudentService(StudentService studentService) {
System.out.println( "[ StudentController ] - [ setStudentService ]" );
this.studentService = studentService;
}
}
5.创建一个ServiceAspect类
@Component//可以标注任意类型组件
@Aspect//标注切面类的注解
public class ServiceAspect {
@Pointcut( "execution(* com..service.*.save*(..))" )//标注切点
private void servicePointcut(){
}
@Before( "servicePointcut()" )//切点方位
public void before( JoinPoint joinPoint ) {
System.out.println( "【 " + joinPoint.getSignature().getName() + " 】方法即将执行" );
}
@Around( "servicePointcut()" )//切点方位
public Object around( ProceedingJoinPoint proceedingJoinPoint ) throws Throwable {
String name = proceedingJoinPoint.getSignature().getName();
System.out.println( "开始为" + name + "计时" );
long begin = System.nanoTime();
Object result = proceedingJoinPoint.proceed();
long end = System.nanoTime();
System.out.print( "为" + name + "计时结束," );
System.out.println( "[ " + name + " ]执行耗时 [ " + ( end - begin ) + "ns, ]" );
return result ;
}
@AfterReturning( pointcut = "servicePointcut()" , returning = "xxx")//切点方位
public void afterReturn( JoinPoint joinPoint , Object xxx ) {
System.out.println("【 " + joinPoint.getSignature().getName() + " 】方法执行后返回了 【 " + xxx +" 】");
}
@AfterThrowing( pointcut = "servicePointcut()" , throwing = "ex")//切点方位
public void afterThrow( JoinPoint joinPoint , Throwable ex ) {
System.out.println("【 " + joinPoint.getSignature().getName() + " 】方法执行执行时抛出 【 " + ex +" 】");
}
@After( "servicePointcut()" )//切点方位
public void after( JoinPoint joinPoint ) {
System.out.println( "【 " + joinPoint.getSignature().getName() + " 】方法执行结束" );
}
}
6.配置文件中添加context和aop命名空间,启用注解
<?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:context="http://www.springframework.org/schema/context"
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:annotation-config />
-->
<!-- 扫描 dao 包中所有的 所有的类 -->
<context:component-scan base-package="com.itlaobing.aop.annotation.dao" />
<!-- 扫描 service 包中所有的 所有的类 -->
<context:component-scan base-package="com.itlaobing.aop.annotation.service" />
<!-- 扫描 controller 包中所有的 所有的类 -->
<context:component-scan base-package="com.itlaobing.aop.annotation.controller" />
<!-- 扫描 aspect 包-->
<context:component-scan base-package="com.itlaobing.aop.annotation.aspect" />
<!-- 告知容器需要为 注解 提供 自动代理支持 -->
<aop:aspectj-autoproxy />
</beans>
7.创建AnnotationBasedAopTest测试类
- 先指定配置文件,创建容器
- 将配置文件放在容器里
- 从容器中获得实例和实例对应的类
- new一个Student对象,设置它的id和name
- 调用 studentService的save方法
public class AnnotationBasedAopTest {
public static void main(String[] args) {
AbstractApplicationContext container = new ClassPathXmlApplicationContext( "classpath*:com/**/annotation/aop-annotation.xml" );
StudentService studentService = container.getBean( "studentService" , StudentService.class);
System.out.println( "Class ==> " + studentService.getClass() );
Student s = new Student();
s.setId( 1001 );
s.setName( "奔波儿灞" );
studentService.save( s );
container.close();
}
}