Spring 核心:FactoryBean

237 篇文章 4 订阅
237 篇文章 1 订阅

我们先简单分析一下mybatis starter的编写,然后再编写自定义的starter。

mybatis中的autoconfigure模块中使用了一个叫做MybatisAutoConfiguration的自动化配置类。

这个MybatisAutoConfiguration需要在这些Condition条件下才会执行:

@ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })。需要SqlSessionFactory和SqlSessionFactoryBean在classpath中都存在
@ConditionalOnBean(DataSource.class)。 spring factory中需要存在一个DataSource的bean
@AutoConfigureAfter(DataSourceAutoConfiguration.class)。需要在DataSourceAutoConfiguration自动化配置之后进行配置,因为mybatis需要数据源的支持
同时在META-INF目录下有个spring.factories这个properties文件,而且它的key为org.springframework.boot.autoconfigure.EnableAutoConfiguration,这样才会被springboot加载:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
有了这些东西之后,mybatis相关的配置会被自动加入到spring container中,只要在maven中加入starter即可:

org.mybatis.spring.boot
mybatis-spring-boot-starter
1.1.1

编写自定义的starter
接下来,我们来编写自定义的starter:log-starter。

这个starter内部定义了一个注解,使用这个注解修饰方法之后,该方法的调用会在日志中被打印并且还会打印出方法的耗时。starter支持exclude配置,在exclude中出现的方法不会进行计算。

pom文件:

org.springframework.boot
spring-boot-starters
1.3.5.RELEASE



org.springframework.boot
spring-boot-starter


定义修饰方法的注解@Log:
package me.format.springboot.log.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retenti

on(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD)

public @interface Log { }
然后是配置类:

package me.format.springboot.log.autoconfigure; import
org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.StringUtils; import
javax.annotation.PostConstruct; @ConfigurationProperties(prefix =
“mylog”) public class LogProperties {

private String exclude;

private String[] excludeArr;

@PostConstruct
public void init() {
    this.excludeArr = StringUtils.split(exclude, ",");
}

public String getExclude() {
    return exclude;
}

public void setExclude(String exclude) {
    this.exclude = exclude;
}

public String[] getExcludeArr() {
    return excludeArr;
} }

接下来是AutoConfiguration:

package me.format.springboot.log.autoconfigure; import
me.format.springboot.log.annotation.Log; import
me.format.springboot.log.aop.LogMethodInterceptor; import
org.aopalliance.aop.Advice; import org.slf4j.Logger; import
org.slf4j.LoggerFactory; import org.springframework.aop.Pointcut;
import org.springframework.aop.support.AbstractPointcutAdvisor; import
org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
import org.springframework.beans.factory.annotation.Autowired; import
org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration; import
javax.annotation.PostConstruct; @Configuration
@EnableConfigurationProperties(LogProperties.class) public class
LogAutoConfiguration extends AbstractPointcutAdvisor {

private Logger logger = LoggerFactory.getLogger(LogAutoConfiguration.class);

private Pointcut pointcut;

private Advice advice;

@Autowired
private LogProperties logProperties;

@PostConstruct
public void init() {
    logger.info("init LogAutoConfiguration start");
    this.pointcut = new AnnotationMatchingPointcut(null, Log.class);
    this.advice = new LogMethodInterceptor(logProperties.getExcludeArr());
    logger.info("init LogAutoConfiguration end");
}

@Override
public Pointcut getPointcut() {
    return this.pointcut;
}

@Override
public Advice getAdvice() {
    return this.advice;
}   }

由于计算方法调用的时候需要使用aop相关的lib,所以我们的AutoConfiguration继承了AbstractPointcutAdvisor。这样就有了Pointcut和Advice。Pointcut是一个支持注解的修饰方法的Pointcut,Advice则自己实现:

package me.format.springboot.log.aop; import
org.aopalliance.intercept.MethodInterceptor; import
org.aopalliance.intercept.MethodInvocation; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.util.Arrays; import
java.util.List; public class LogMethodInterceptor implements
MethodInterceptor {
private Logger logger = LoggerFactory.getLogger(LogMethodInterceptor.class);
private List exclude;
public LogMethodInterceptor(String[] exclude) {
this.exclude = Arrays.asList(exclude);
}
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
String methodName = invocation.getMethod().getName();
if(exclude.contains(methodName)) {
return invocation.proceed();
}
long start = System.currentTimeMillis();
Object result = invocation.proceed();
long end = System.currentTimeMillis();
logger.info(“====method({}), cost({}) “, methodName, (end - start));
return result;
} }

最后resources/META-INF/spring.factories中加入这个AutoConfiguration:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
me.format.springboot.log.autoconfigure.LogAutoConfiguration

我们在项目中使用这个log-starter:


me.format.springboot
log-starter
1.0-SNAPSHOT

使用配置:

mylog.exclude=core,log

然后编写一个简单的Service:

@Service public class SimpleService {

@Log
public void test(int num) {
    System.out.println("----test---- " + num);
}

@Log
public void core(int num) {
    System.out.println("----core---- " + num);
}

public void work(int num) {
    System.out.println("----work---- " + num);
}   }

使用单元测试分别调用这3个方法,由于work方法没有加上@Log注解,core方法虽然加上了@Log注解,但是在配置中被exclude了,只有test方法可以正常计算耗时:

—-test—- 666 2016-11-16 01:29:32.255 INFO 41010 — [ main] m.f.s.log.aop.LogMethodInterceptor : ====method(test),
cost(36)
—-work—- 666
—-core—- 666

总结:

自定义springboot的starter,注意这两点。

如果自动化配置类需要在程序启动的时候就加载,可以在META-INF/spring.factories文件中定义。如果本次加载还需要其他一些lib的话,可以使用ConditionalOnClass注解协助
如果自动化配置类要在使用自定义注解后才加载,可以使用自定义注解+@Import注解或@ImportSelector注解完成

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
校园悬赏任务平台对字典管理、论坛管理、任务资讯任务资讯公告管理、接取用户管理、任务管理、任务咨询管理、任务收藏管理、任务评价管理、任务订单管理、发布用户管理、管理员管理等进行集中化处理。经过前面自己查阅的网络知识,加上自己在学校课堂上学习的知识,决定开发系统选择小程序模式这种高效率的模式完成系统功能开发。这种模式让操作员基于浏览器的方式进行网站访问,采用的主流的Java语言这种面向对象的语言进行校园悬赏任务平台程序的开发,在数据库的选择上面,选择功能强大的Mysql数据库进行数据的存放操作。校园悬赏任务平台的开发让用户查看任务信息变得容易,让管理员高效管理任务信息。 校园悬赏任务平台具有管理员角色,用户角色,这几个操作权限。 校园悬赏任务平台针对管理员设置的功能有:添加并管理各种类型信息,管理用户账户信息,管理任务信息,管理任务资讯公告信息等内容。 校园悬赏任务平台针对用户设置的功能有:查看并修改个人信息,查看任务信息,查看任务资讯公告信息等内容。 系统登录功能是程序必不可少的功能,在登录页面必填的数据有两项,一项就是账号,另一项数据就是密码,当管理员正确填写并提交这二者数据之后,管理员就可以进入系统后台功能操作区。项目管理页面提供的功能操作有:查看任务,删除任务操作,新增任务操作,修改任务操作。任务资讯公告信息管理页面提供的功能操作有:新增任务资讯公告,修改任务资讯公告,删除任务资讯公告操作。任务资讯公告类型管理页面显示所有任务资讯公告类型,在此页面既可以让管理员添加新的任务资讯公告信息类型,也能对已有的任务资讯公告类型信息执行编辑更新,失效的任务资讯公告类型信息也能让管理员快速删除。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值