前言

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. (六)mybatis拦截器

    首先拦截器可以拦截mybatis四大核心对象:StatementHandler,ParameterHandler,ResultSetHandler,Executor,具体拦截时根据需求拦截一部分方法 ...

  2. 安装Debian的磨磨唧唧

    安装Debian的磨磨唧唧 唆使VMware罢工的微软 这两天心血来潮想折腾,拆了我亲爱的Ubuntu.装个Debian 不过因为加入了微软的insider版本 就很尴尬的发现当我打开我的VMware ...

  3. qt creator源码全方面分析(2-10-4)

    目录 Plugin Life Cycle Plugin Life Cycle 为了能够编写Qt Creator插件,您必须了解启动或关闭Qt Creator时,插件管理器所采取的步骤. 本节详细描述插 ...

  4. lwip的内存管理

    lwip可以不用malloc,而完全用pool,全用全局变量,没看明白怎么实现的. #if LWIP_NETCONN || LWIP_SOCKET LWIP_MEMPOOL(NETBUF, MEMP_ ...

  5. Ansible 学习目录

    1. Ansible 安装 2. Ansible hosts 文件配置 3. Ansible 常用模块 4. Ansible playbook使用

  6. xmake v2.3.1 发布, 无缝对接其他构建系统

    最近对xmake内部做了不少的重构来改进,并且新增了不少实用的新特性,欢迎来体验. 项目源码 官方文档 一些新特性: 一键编译其他构建系统维护的项目,实现无缝对接,并且支持交叉编译(比如autotoo ...

  7. SQLPLUS ed无法调出编辑面板 SP2-0107:无须保存

    现象: 重新启动oracle启动sqlplus,首先执行ed命令时出错,没有调出编辑命令的文件: SQL> edSP2-0107: 无须保存. 分析:出错的原因可能是临时编辑文件中没有需要执行的 ...

  8. pyhton项目和晋江文学城数据分析项目

     1.图书管理系统 图1.图书管理系统(作者信息列表页面) 图2.图书管理系统(作者信息修改页面) 2.个人博客网页设计 图3.博客(我的日记-->个人日记)页面 图4.博客(关于我--> ...

  9. POST注入之sqlmap

    POST注入方法一加—form跑数据库sqlmap.py -u http://59.63.200.79:8815/Pass-05/index.php —form —dbs跑出数据库后查询表名 假设库名 ...

  10. 处理方法返回值void

    1.默认响应效果:根据请求url寻找相应页面 1.1.配置的视图解析器 <!--配置视图解析器--> <bean id="internalResourceViewResol ...