前言

github: https://github.com/vergilyn/SpringBootDemo

一、AOP

官方demo:https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-aop

1.1 pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
1.2 demo

对aop的properties配置有:

#### AOP
# spring.aop.auto=true # Add @EnableAspectJAutoProxy.
# spring.aop.proxy-target-class=false # Whether subclass-based (CGLIB) proxies are to be created (true) as opposed to standard Java interface-based proxies (false).

这两个配置都允许注解配置: @EnableAspectJAutoProxy (proxyTargetClass = false,exposeProxy = false),默认值都是false
    代码目录:

代码说明:

1. AopService:被aop增强的class。

AopAspect:aop增强的class。

AopApplication:启动、测试class。

2. 整个demo很简单,实际要用到再去细看AOP也可以。

@Component
public class AopService {
@Value("${aop.name:Dante}")
private String name; public String getMsg() {
return "Hello, " + this.name;
}
}
@Aspect
@Component
public class AopAspect {
@AfterReturning("execution(* com.vergilyn.demo.springboot.aop.*Service.*(..))")
public void afterReturning(JoinPoint joinPoint) {
System.out.println("aop @AfterReturning: " + joinPoint);
}
}
@SpringBootApplication
//开启aop支持; 可properties配置proxyTargetClass、exposeProxy
//@EnableAspectJAutoProxy //(proxyTargetClass = true,exposeProxy = false)
public class AopApplication implements CommandLineRunner {
@Autowired
private AopService aopService; public static void main(String[] args) {
SpringApplication app = new SpringApplication(AopApplication.class);
app.setAdditionalProfiles("aop");
app.run(args);
} @Override
public void run(String... args) {
System.out.println(this.aopService.getMsg());
}
}

aop.name=vergilyn

#### AOP
# spring.aop.auto=true # Add @EnableAspectJAutoProxy.
# spring.aop.proxy-target-class=false # Whether subclass-based (CGLIB) proxies are to be created (true) as opposed to standard Java interface-based proxies (false).

application-aop.properties

console输出结果:

aop @AfterReturning: execution(String com.vergilyn.demo.springboot.aop.AopService.getMsg())
Hello, vergilyn

二、自定义注解

其实我本来是要做的是:自定义注解注入Logger,所以才顺道写了一下AOP的demo。

需求:

1. 通过注解,注入Logger(org.apache.log4j.Logger)。

说明:

之前注入日志都是在每个类中写代码,ex:

public class XXclass{
private Logger log = Logger.getLogger(XXclass.class);
}

现在想通过自定义注解注入,ex:

public class XXclass{
private Logger log1 = Logger.getLogger(XXclass.class); @Log //自定义注解
private Logger log2;
}

其中log2的效果与log1一样。

实现:

1. 可以通过aop注入。

2. 可以通过实现org.springframework.beans.factory.config.BeanPostProcessor注入;

(其实是一样的,了解spring的就知道Bean的注入都会通过BeanPostProcessor)

代码demo:

注解Log的定义

@Retention(RUNTIME)
@Target(FIELD)
@Documented
@Inherited
public @interface Log { }

注解的实现

@Component
@Aspect
public class LogInjector implements BeanPostProcessor { public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
return bean;
} public Object postProcessBeforeInitialization(final Object bean,String beanName) throws BeansException {
ReflectionUtils.doWithFields(bean.getClass(), new FieldCallback() {
public void doWith(Field field) throws IllegalArgumentException,
IllegalAccessException {
// System.out.println("Logger Inject into :" + bean.getClass());
// make the field accessible if defined private
ReflectionUtils.makeAccessible(field);
if (field.getAnnotation(Log.class) != null) {
Logger log = Logger.getLogger(bean.getClass());
field.set(bean, log);
}
}
});
return bean;
}
}

启动、测试类

@SpringBootApplication
public class AnnotationApplication implements CommandLineRunner{
@Log
private Logger log; public static void main(String[] args) {
SpringApplication app = new SpringApplication(AnnotationApplication.class);
app.setAdditionalProfiles("log");
app.run(args);
} @Override
public void run(String... args) throws Exception {
System.out.println("log : " + log);
log.info("log 注解注入成功. log:" + log);
}
}

输出结果:

log : org.apache.log4j.Logger@24d31b86
2017-03-19 19:44:34.576 INFO 7688 --- [ restartedMain] ication$$EnhancerBySpringCGLIB$$52ae5e8e : log 注解注入成功. log:org.apache.log4j.Logger@24d31b86

三、扩展:spring boot之@Import、@ImportResource

缘由:由于我代码的目录结构是,一个project中根据package不同(因为spring boot默认扫描启动类所在的包,及其子包),测试spring boot的各种功能。

比如图中的*Application.class都是spring boot的启动类。然而我想把前面写的Log注解用在所有的*Application对应的项目中。

这就迁出一个问题:*Application.class只扫描所在的package及其sub-packages。从目录结构可以看到,Log并不能被别的*Application.class扫描到。

所以,要怎么解决呢?

这就需要spring boot提供的注解:@Import、@ImportResource。ex:

@SpringBootApplication
@EnableScheduling //通过@EnableScheduling注解开启对计划任务的支持
//@ImportResource(locations = "ConfigXML/annotation-scan.xml" )
@Import(value = LogInjector.class)
public class TimmerApplication {
public static void main(String[] args) {
SpringApplication.run(TimmerApplication.class, args);
}
}

对于@ImportResource需要通过xml注入bean(就是普通的spring),annotation-scan.xml:

<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:mvc="http://www.springframework.org/schema/mvc" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"> <!-- 扫描公共组件 -->
<context:component-scan base-package="com.vergilyn.demo.annotation" /> </beans>

【spring boot】SpringBoot初学(6)– aop与自定义注解的更多相关文章

  1. Java Spring Boot VS .NetCore (十一)自定义标签 Java Tag Freemarker VS .NetCore Tag TagHelper

    Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...

  2. Spring Boot → 08:嵌入式Servlet容器自定义

    Spring Boot → 08:嵌入式Servlet容器自定义

  3. Java Spring Boot VS .NetCore (八) Java 注解 vs .NetCore Attribute

    Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...

  4. SpringBoot 源码解析 (十)----- Spring Boot的核心能力 - 集成AOP

    本篇主要集成Sping一个重要功能AOP 我们还是先回顾一下以前Spring中是如何使用AOP的,大家可以看看我这篇文章spring5 源码深度解析----- AOP的使用及AOP自定义标签 Spri ...

  5. Spring Boot系列——AOP配自定义注解的最佳实践

    AOP(Aspect Oriented Programming),即面向切面编程,是Spring框架的大杀器之一. 首先,我声明下,我不是来系统介绍什么是AOP,更不是照本宣科讲解什么是连接点.切面. ...

  6. Spring Boot 2.0 教程 | AOP 切面统一打印请求日志

    欢迎关注微信公众号: 小哈学Java 文章首发于个人网站 https://www.exception.site/springboot/spring-boot-aop-web-request 本节中,您 ...

  7. 用AOP拦截自定义注解并获取注解属性与上下文参数(基于Springboot框架)

    目录 自定义注解 定义切面 获取上下文信息JoinPoint ProceedingJoinPoint 定义测试方法 测试结果 小结 AOP可以用于日志的设计,这样话就少不了要获取上下文的信息,博主在设 ...

  8. Spring Boot(五):Spring Boot的启动器Starter大全及自定义Starter

    现有启动器Starter目录 Spring Boot应用启动器基本的一共有44种,具体如下: 1)spring-boot-starter 这是Spring Boot的核心启动器,包含了自动配置.日志和 ...

  9. SpringBoot框架:通过AOP和自定义注解完成druid连接池的动态数据源切换(三)

    一.引入依赖 引入数据库连接池的依赖--druid和面向切面编程的依赖--aop,如下所示: <!-- druid --> <dependency> <groupId&g ...

随机推荐

  1. 数据清洗:按照进行数据清洗,并将清洗后的数据导入hive数据库中。

    虚拟机: hadoop:3.2.0 hive:3.1.2 win10: eclipse 两阶段数据清洗: (1)第一阶段:把需要的信息从原始日志中提取出来 ip:    199.30.25.88 ti ...

  2. Python3(八) 枚举详解

    一.枚举其实是一个类 建议标识名字用大写 1.枚举类: from enum import Enum class VIP(Enum):     YELLOW = 1     GREEN = 2      ...

  3. Vue过滤器、生命周期函数和vue-resource

    一.过滤器 使用例子: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...

  4. Python2-Django配置阿里大于的短信验证码接口

    1.短信发送开发指南地址:https://help.aliyun.com/document_detail/55491.html?spm=a2c4g.11186623.6.568.l5zTwH 2.SD ...

  5. 1994_An Algorithm To Reconstruct Wideband Speech From Narrowband Speech Based On Codebook Mapping

    论文地址:基于码本映射的窄带语音宽带重建算法 博客作者:凌逆战 博客地址:https://www.cnblogs.com/LXP-Never/p/12144324.html 摘要 本文提出了一种从窄带 ...

  6. vue 使用v-for进行循环

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. ORACLE中如何找出大表分布在哪些数据文件中?

    ORACLE中如何找出大表分布在哪些数据文件中?   在ORACLE数据中,我们能否找出一个大表的段对象分布在哪些数据文件中呢? 答案是可以,我们可以用下面脚本来找出对应表的区.段分别位于哪些数据文件 ...

  8. 1.Android网络编程-HTML介绍

    1.HTML介绍 超文本标记语言(HyperText Markup Language,简称:HTML)是一种用于创建网页的标准标记语言. 在Eclipse下则可以使用自带的浏览器浏览html: 2.H ...

  9. Openshift中Pod的SpringBoot2健康检查

    Openshift中Pod的SpringBoot2应用程序健康检查 1. 准备测试的SpringBoot工程, 需要Java 8 JDK or greater and Maven 3.3.x or g ...

  10. window10家庭版解决IIS中万维网服务的安全性中无Windows身份验证

    首先在左下角输入cmd搜索->命令提示符->以管理员身份运行->然后复制下面一段命令: dism /online /norestart /add-package:%SystemRoo ...