前文对 Spring IoC 和 Spring AOP 的实现方法进行了整合。如果有不明白的或有质疑的地方可以评论出来,一起探讨问题,帮助别人也是帮助自己!本文探讨的中心主要放在 Spring 的注解上。对于 Spring ,我也是个初学者,文中也许会出现其他作者总结中出现的内容,在这里感谢原作者。

注解的基本概念和原理

注解(Annotation)提供了一种安全的类似注释的机制,为我们在代码中添加信息提供了一种形式化得方法,使我们可以在稍后某个时刻方便的使用这些数据(通过解析注解来使用这些数据),用来将任何的信息或者元数据与程序元素(类、方法、成员变量等)进行关联。其实就是更加直观更加明了的说明,这些说明信息与程序业务逻辑没有关系,并且是供指定的工具或框架使用的。Annotation 像一种修饰符一样,应用于包、类型、构造方法、方法、成员变量、参数及本地变量的申明语句中。

Annotation 其实是一种接口。通过 Java 的反射机制相关的API来访问 Annotation 信息。相关类(框架或工具中的类)根据这些信息来决定如何使用该程序元素或改变它们的行为。Java 语言解释器在工作时会忽略这些 Annotation ,因此在 JVM 中这些Annotation 是“不起作用”的,只能通过配套的工具才能对这些 Annotation 类型的信息进行访问和处理。

自定义一个注解

  1. import java.lang.annotation.ElementType;
  2. import java.lang.annotation.Retention;
  3. import java.lang.annotation.RetentionPolicy;
  4. import java.lang.annotation.Target;
  5.  
  6. // 在运行时执行
  7. @Retention(RetentionPolicy.RUNTIME)
  8. // 注解适用地方(字段和方法)
  9. @Target({ ElementType.FIELD, ElementType.METHOD })
  10. public @interface AnnotationTest {
  11.  
  12. // 注解的name属性
  13. public String name() default "";
  14. }

有关注解的详细信息可以查阅相关开发文档,这里不再赘述。

Spring 注解的作用

Spring 的一个核心功能是 IoC,就是将 Bean 初始化加载到容器中,Bean 是如何加载到容器的,可以使用 Spring 注解方式或者 Spring XML 配置方式。
Spring 注解方式减少了配置文件内容,更加便于管理,并且使用注解可以大大提高了开发效率!使用 Spring 框架进行开发,注解是必不可少的一部分,可以说是非常重要了。

使用 Spring 注解需要的 jar 包

  • com.springsource.org.aopalliance-1.0.0.jar
  • com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
  • spring-aop-4.2.5.RELEASE.jar
  • spring-aspects-4.2.5.RELEASE.jar

注解类介绍

@Component :标准一个普通的spring Bean类。
@Repository:标注一个DAO组件类。
@Service:标注一个业务逻辑组件类。
@Controller:标注一个控制器组件类。

使用 @Component 注解定义Bean

  1. import org.springframework.stereotype.Component;
  2. import org.springframework.stereotype.Repository;
  3.  
  4. // 通过注解定义一个DAO
  5. @Component("userDao")
  6. public class UserDaoImpl implements IUserDao {
  7.  
  8. @Override
  9. public void addUser(User user) {
  10. // 这里并未实现完整数据库操作,仅为说明问题
  11. System.out.println("add user");
  12. }
  13.  
  14. }

@Component( "userDao" ) 的作用与在 XML 配置文件中编写 <bean id= "userDao"  class= "dao.impl.UserDaoImpl"  /> 等效。

使用 @Autowired 注解实现Bean组件装配

  1. import org.springframework.beans.factory.annotation.Autowired;
  2. import org.springframework.beans.factory.annotation.Qualifier;
  3. import org.springframework.stereotype.Service;
  4.  
  5. @Service("userService")
  6. public class UserServiceImpl implements IUserService {
  7.  
  8. // 声明接口类型的引用和具体实现类解耦合
  9. @Autowired
  10. @Qualifier("userDao")
  11. private IUserDao dao;
  12.  
  13. @Override
  14. public void addUser(User user) {
  15. dao.addUser(user);
  16. }
  17. }

@Autowired 是根据类型进行自动装配的。如果当 Spring上下文中存在不止一个 UserDao 类型的bean时,就会抛出 BeanCreationException 异常;如果 Spring 上下文中不存在 UserDao 类型的 Bean ,也会抛出 BeanCreationException 异常。我们可以使用@Qualifier 配合 @Autowired 来解决这些问题。

使用 Java 标准注解 @Resource 完成装配

  1. import javax.annotation.Resource;
  2. import org.springframework.stereotype.Service;
  3. @Service("userService")
  4. public class UserServiceImpl implements IUserService {
  5.  
  6. // 查找名为 dao 的 Bean,并注入给 dao 属性
  7. @Resource(name = "userDao")
  8. private IUserDao dao;
  9. @Override
  10. public void addUser(User user) {
  11. dao.addUser(user);
  12. }
  13.  
  14. }

@Resource 有一个 name 属性,默认情况下,Spring 将这个属性的值解释为要注入的 Bean 的名称。

如果没有显示地指定 Bean 的名称,且无法找到与默认 Bean 名称匹配的 Bean 组件,@Resource 会由按名称查找的方式自动变为按类型匹配的方式进行装配。

使用注解定义切面

Spring 通过集成 AspectJ 实现了以注解的方式定义切面,大大减少了配置文件的工作量。AspectJ是一个面向切面的框架,它扩展了 Java 语言,定义了 AOP 语法,能够在编译期提供代码的织入,所以它有一个专门的编译器用来生成遵守字节编码规范的Class 文件。@AspectJ 是 AspectJ 5 新增的功能,使用 JDK 5.0 注解技术和正规的 AspectJ 切点表达式语言描述切面,因此在使用 @AspectJ 之间,需要保证所使用的 JDK 是 5.0 或其以上版本,否则无法使用注解技术

要进行 AOP 编程,我们首先要在 Spring 配置文件中引入 aop 命名空间

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/context
  9. http://www.springframework.org/schema/context/spring-context-4.2.xsd
  10. http://www.springframework.org/schema/aop
  11. http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
  12.  
  13. </beans>

使用注解标注切面

首先看一下增强类代码

  1. import org.apache.log4j.Logger;
  2. import org.aspectj.lang.JoinPoint;
  3. import org.aspectj.lang.ProceedingJoinPoint;
  4. import org.aspectj.lang.annotation.AfterReturning;
  5. import org.aspectj.lang.annotation.AfterThrowing;
  6. import org.aspectj.lang.annotation.Around;
  7. import org.aspectj.lang.annotation.Aspect;
  8. import org.aspectj.lang.annotation.Pointcut;
  9. import org.springframework.stereotype.Component;
  10.  
  11. @Aspect
  12. @Component("serviceAdviceLogging")
  13. public class ServiceAdviceLogging {
  14. private Logger logger = Logger.getLogger(ServiceAdviceLogging.class);
  15.  
  16. // 注解定义切点 参数为定义切点的表达式部分
  17. @Pointcut("execution(* cn.zdpz.service..*.*(..))")
  18. public void pointcutLogging(){}
  19.  
  20. // 注解实现后置增强
  21. @AfterReturning("pointcutLogging()")
  22. public void afterReturning(JoinPoint joinPoint){
  23. String simpleClassName = joinPoint.getSignature().getName();
  24. String methodName = joinPoint.getTarget().getClass().getName();
  25. logger.info(simpleClassName+"-----"+methodName+"后置增强方法");
  26. }
  27.  
  28. // 注解实现异常增强
  29. @AfterThrowing(pointcut="pointcutLogging()",throwing="e")
  30. public void afterThrowing(JoinPoint joinPoint,Exception e){
  31. String simpleClassName = joinPoint.getSignature().getName();
  32. String methodName = joinPoint.getTarget().getClass().getName();
  33. logger.info(simpleClassName+"-----"+methodName+"出现异常:"+e.getMessage());
  34. }
  35.  
  36. // 注解实现环绕增强
  37. @Around("pointcutLogging()")
  38. public Object around(ProceedingJoinPoint proceedingJoinPoint){
          Object obj = null;
  39. try {
  40. System.out.println("环绕增强前:");
  41. obj = proceedingJoinPoint.proceed();
  42. System.out.println("环绕增强后:");
  43. } catch (Throwable e) {
  44. e.printStackTrace();
  45. }
          return obj;
  46. }
  47. }

上面的代码

使用 @Aspect 注解将 ServiceAdviceLogging 定义为切面

使用 @AfterReturning 注解将 afterReturning() 方法定义为后置增强

使用 @AfterThrowing 注解将 afterThrowing() 方法定义为异常增强

使用 @Around 注解将 around() 方法定义为环绕增强

一定要看的 注意点总结

1.被注解的 Java 类当做 Bean 实例,Bean 实例的名称默认是 Bean 类的首字母小写,其他部分不变。@Service 也可以自定义 Bean 名称,但是必须是唯一的!

2.尽量使用对应组件注解的类替换 @Component 注解,在 spring 未来的版本中,@Controller,@Service,@Repository会携带更多语义。并且便于开发和维护。

3.指定了某些类可作为 Spring Bean 类使用后,最好还需要让spring搜索指定路径,在Spring配置文件加入如下配置:

  1.  
  1. <!-- 自动扫描指定包及其子包下的所有Bean类 -->
  2. <context:component-scan base-package="org.springframework.*"/>
  1.  

4.使用 AOP 编程要通过 aop 命名空间的 <aop:aspectj-autoproxy /> 声明自动为 spring 容器中那些配置 @aspectJ 切面的 bean 创建代理,织入切面。

  1. <!-- 自动为切面方法中匹配的方法所在的类生成代理对象。 -->
  2. <aop:aspectj-autoproxy />

下次更新MyBatis+Spring整合

  1.  

【Java】关于Spring框架的总结 (三)的更多相关文章

  1. spring框架学习(三)junit单元测试

    spring框架学习(三)junit单元测试 单元测试不是头一次听说了,但只是听说从来没有用过.一个模块怎么测试呢,是不是得专门为一单元写一个测试程序,然后将测试单元代码拿过来测试? 我是这么想的.学 ...

  2. Spring框架的第三天

    ## Spring框架的第三天 ## ---------- **课程回顾:Spring框架第二天** 1. IOC的注解方式 * @Value * @Resource(name="" ...

  3. 自己写一个java的mvc框架吧(三)

    自己写一个mvc框架吧(三) 根据Method获取参数并转换参数类型 上一篇我们将url与Method的映射创建完毕,并成功的将映射关系创建起来了.这一篇我们将根据Method的入参参数名称.参数类型 ...

  4. JAVA总结--Spring框架全解

    一.Spring简介 Spring 是个java企业级应用的开源开发框架.Spring主要用来开发Java应用,但是有些扩展是针对构建J2EE平台的web应用.Spring 框架目标是简化Java企业 ...

  5. spring框架学习(三)

    一.Spring自动组件扫描 Spring 提供组件扫描(component scanning)功能.它能从指定的classpath里自动扫描.侦测和实例化具有特定注解的组件. 基本的注解是@Comp ...

  6. java 之 Spring 框架(Java之负基础实战)

    1.Spring是什么 相当于安卓的MVC框架,是一个开源框架.一般用于轻型或中型应用. 它的核心是控制反转(IoC)和面向切面(AOP). 主要优势是分层架构,允许选择使用哪一个组件.使用基本的Ja ...

  7. 10 Spring框架 AOP (三) Spring对AspectJ的整合

    上两节我们讲了Spring对AOP的实现,但是在我们的开发中我们不太使用Spring自身的对AOP的实现,而是使用AspectJ,AspectJ是一个面向切面的框架,它扩展了Java语言.Aspect ...

  8. java:Spring框架1(基本配置,简单基础代码模拟实现,spring注入(DI))

    1.基本配置: 步骤一:新建项目并添加spring依赖的jar文件和commons-logging.xx.jar: 步骤二:编写实体类,DAO及其实现类,Service及其实现类; 步骤三:在src下 ...

  9. java:Spring框架3(AOP,SSH集成Demo)

    1.AOP: Spring提供了4种实现AOP的方式: 1.经典的基于代理的AOP 2.@AspectJ注解驱动的切面 3.纯POJO切面 4.注入式AspectJ切面 aop.xml: <?x ...

  10. 详解Java的Spring框架中的注解的用法

    转载:http://www.jb51.net/article/75460.htm 1. 使用Spring注解来注入属性 1.1. 使用注解以前我们是怎样注入属性的 类的实现: class UserMa ...

随机推荐

  1. 思维导图与Spring Batch

    最近在学画图,又在复习Spring Batch.不解释,直接上图. 第三章,用XMind画的. 第五章,用iMindMap画的.

  2. springMVC通过ajax传参到后台

    JSON对象和JSON字符串 在SpringMVC环境中,@RequestBody接收的是一个Json对象的字符串,而不是一个Json对象.然而在ajax请求往往传的都是Json对象,用 JSON.s ...

  3. 异常:Caused by: java.lang.NoSuchMethodError: javax.persistence.OneToMany.orphanRemoval()Z

    Spring3.0 + Hibernate3.5:启动服务器报:Caused by: java.lang.NoSuchMethodError: javax.persistence.OneToMany. ...

  4. W5100与MCU的连接方式

    W5100与MCU的连接方式 W5100与MCU的连接方式主要有直接总线连接.间接总线连接.SPI总线连接这三种连接方法,不同的连接方法适应于不同的场合,应该按需选择最恰当的连接方式. 1)直接总线连 ...

  5. 20165322 实验三 敏捷开发与XP实践

    实验三 敏捷开发与XP实践 安装alibaba 插件,解决代码中的规范问题 根据老师的教程:打开Settings ->Plugins -> Browse repositories...在搜 ...

  6. ubuntu误删home目录

    今天第一次写shell脚本,一不小心把home目录全给删除了. 解决方案: 先把手打上二十大板!!! [root@myshell ~]#mkdir /home/test01             / ...

  7. 【转】有关onpropertychange事件

    <div style="border:1px solid #fc0;height:24px;width:300px;" id="target">&l ...

  8. Android学习笔记_37_ListView批量加载数据和页脚设置

    1.在activity_main.xml布局文件中加入ListView控件: <RelativeLayout xmlns:android="http://schemas.android ...

  9. HTML5之canvas基本API介绍及应用 1

    一.canvas的API: 1.颜色.样式和阴影: 2.线条样式属性和方法: 3.路径方法: 4.转换方法: 5.文本属性和方法: 6.像素操作方法和属性: 7.其他: drawImage:向画布上绘 ...

  10. cuda 8.0, ssd

    error info and resolution: https://github.com/weiliu89/caffe/issues/38 https://github.com/weiliu89/c ...