https://www.cnblogs.com/niejunlei/p/5980544.html
Spring Boot 基于注解式开发 maven REST 示例项目
项目地址:https://github.com/windwant/spring-boot-test
项目特色:
1. servlet、listener、interceptor、filter配置
2. mybatis配置集成,多数据源 RouingDataSource
3. 集成jmx监控 MBean
4. 定时任务配置 Scheduled
5. aop配置
6. ftp服务 FTPTranport
7. 测试 SpringBootTest
8. Metrics监控
9. 参数验证 javax.validation hibernate.validator
a) 测试:/hellox?name=
10. 跨域处理 Cors
11. 权限控制 shiro权限框架
a) 测试用户:userName: admin passwd: admin
b) 验证码:/login/checkcode
c) 登录:/login?userName=&passwd=&code=
d) 测试:/hellox?name=
12. 导出Excel SXSSFWorkBook 海量数据导出
a) 测试:/export
13. Consul服务注册与发现;
a) 服务启动注册到consul;
b) 测试获取redis服务,初始化redis资源;
c) consul 监控redis服务;
d) 注意consul客户端和consul程序版本问题
14. reids分布式锁
a) lua脚本 获取redis分布式锁
15. SPI机制:org/windwant/spring/core/spi
a) 运行时配置:META-INF/services/org.windwant.spring.core.spi.Calc
16. static资源,“/”映射
17. 使用druid数据源连接池;配置druid数据源监控:http://localhost:8081/druid/index.html
18. Dubbo RPC 服务
一、 Web servlet、listener、interceptor等
1. servlet:
启动类添加注解@ServletComponentScan
编写servlet:
@WebServlet("/web")
public class BootSevlet implements Servlet {...
2. Interceptor:
编写:
/**
* BootInterceptor*/public class BootInterceptor implements HandlerInterceptor {...
注册:WebMvcConfigurerAdapter->addInterceptor方法。
@Configurationpublic class ApplicationConfig {@Configurationpublic class WebMvcConfigurer extends WebMvcConfigurerAdapter {public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new BootInterceptor()).addPathPatterns("/**");super.addInterceptors(registry);
}...
3. listenenr:实现各种listener
@WebListenerpublic class BootListener implements ServletContextListener {...
二、mybatis配置集成,多数据源配置
配置文件:
1. 接口方式开发dao,扫描包配置 :@MapperScan(basePackages = "org.windwant.spring.mapper")
2. 配置dataSource,sqlSessionFactory
datasource 根据application.yml配置的数据源配置
application.yml
datasource:local:url: $[datasource.local.url]username: $[datasource.local.user]password: $[datasource.local.password]driverClassName: com.mysql.jdbc.Drivertype: org.apache.commons.dbcp.BasicDataSourcemax-active: 30max-idle: 10max-wait: 10test-while-idle: trueremote:url: $[datasource.remote.url]username: $[datasource.remote.user]password: $[datasource.remote.password]driverClassName: com.mysql.jdbc.Drivertype: org.apache.commons.dbcp.BasicDataSourcemax-active: 30max-idle: 10max-wait: 10test-while-idle: true
DataSource 注解配置:
/**
* Created by windwant on 2016/12/30.* implements EnvironmentAware, ApplicationContextAware*/@Configurationpublic class MybatisConfig {// private Environment environment;
//
// @Override
// public void setEnvironment(Environment environment) {
// this.environment = environment;
// }
@Primary@Bean(name = "localDataSource")
@Order(value = 1)@ConfigurationProperties(prefix = "datasource.local")
public DataSource localDataSource(){
return DataSourceBuilder.create().build();}@Order(value = 2)@Bean(name = "remoteDataSource")
@ConfigurationProperties(prefix = "datasource.remote")
public DataSource remoteDataSource() {
return DataSourceBuilder.create().build();}@Bean(name = "routingDataSource")
@Order(value = 3)public DataSource routingDataSource(@Qualifier("localDataSource") DataSource localDataSource,@Qualifier("remoteDataSource") BasicDataSource remoteDataSource){
RoutingDataSource routingDataSource = new RoutingDataSource();Map<Object, Object> dataSources = new HashMap<>();dataSources.put(Type.LOCAL.name(), localDataSource);dataSources.put(Type.REMOTE.name(), remoteDataSource);routingDataSource.setTargetDataSources(dataSources);routingDataSource.setDefaultTargetDataSource(localDataSource);return routingDataSource;}@Bean@Order(value = 4)@Lazypublic SqlSessionFactory sqlSessionFactory(@Qualifier("remoteDataSource") DataSource remoteDataSource,@Qualifier("localDataSource") DataSource localDataSource,
@Qualifier("routingDataSource") DataSource routingDataSource) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();factoryBean.setDataSource(routingDataSource);factoryBean.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mybatis/*.xml"));
factoryBean.afterPropertiesSet();return factoryBean.getObject();
}// private ApplicationContext ctx;
//
// @Override
// public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
// this.ctx = applicationContext;
// }
}
项目添加Bean配置:
@Beanpublic MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurerProxy mapperScannerConfigurerProxy = new MapperScannerConfigurerProxy();mapperScannerConfigurerProxy.setBasePackage("org.windwant.spring.mapper");
return mapperScannerConfigurerProxy;}
三、集成jmx监控 MBean
/**
* Created by windwant on 2017/4/6.* JMX Mbean 监控 可以通过jconsole进行mbean暴露操作*/@Component@ManagedResource(description = "sboot svr")
public class WAMBean {// 属性
private String name;private int age;private String message;@ManagedAttributepublic String getName() {System.out.println("name: " + name);
return name;}@ManagedAttributepublic void setName(String name) {this.name = name;}@ManagedAttributepublic int getAge() {System.out.println("age: "+age);
return age;}@ManagedAttributepublic void setAge(int age) {this.age = age;}@ManagedAttributepublic String getMessage() {System.out.println("message: " + message);
return message;}@ManagedAttributepublic void setMessage(String message) {this.message = message;}@ManagedOperation@ManagedOperationParameter(name = "message", description = "message")public void call(String message) {System.out.println("call:" + message);
}@ManagedOperation@ManagedOperationParameter(name = "who", description = "who")@ManagedOperationParameter(name = "what", description = "what")public void look(String who, String what){System.out.println(who + " 发现了 " + what);
}@AutowiredFTPTransport ftpTransport;@ManagedOperationpublic void upload() throws FileNotFoundException {
FileInputStream f = null;try {f = new FileInputStream(new File("D:\\a.json"));ftpTransport.uploadFile("ajson", f);
}catch (Exception e){e.printStackTrace();}finally {try {if(f != null){
f.close();}}catch (Exception e){e.printStackTrace();}}System.out.println("to play....");
}}
四:定时任务配置 Scheduled
@Componentpublic class BootJob {private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");@Scheduled(fixedRate = 1000)public void reportTime(){
System.out.println("current time is: " + dateFormat.format(new Date()));
}}
五:参数验证
参数Bean:验证注解 @NotBlank @NotNull等
public class Guest {@NotBlank(message = "{guest.name}")
private String name;private Integer sex;
Controller:参数添加@Valid注解
@RequestMapping("/hellox")
Map<String, Object> hellox(@Valid Guest guest, BindingResult result){
if(result.hasErrors()){
return Response.response(-1, Constants.FAILED, result.getAllErrors());}
使用lang验证提示信息:
@Beanpublic LocalValidatorFactoryBean localValidatorFactoryBean(){
LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();localValidatorFactoryBean.setProviderClass(HibernateValidator.class);
ReloadableResourceBundleMessageSource rrbms = new ReloadableResourceBundleMessageSource();rrbms.setBasename("classpath:/lang/messages");
rrbms.setUseCodeAsDefaultMessage(false);rrbms.setDefaultEncoding("UTF-8");
localValidatorFactoryBean.setValidationMessageSource(rrbms);return localValidatorFactoryBean;}
六:跨域处理 Cors
配置WebMvcConfigureAdapter addCorsMappings
addMapping:请求拦截
allowedOrigins:拦截请求源
allowedMethods:拦截方法
@Configuration
public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new BootInterceptor()).addPathPatterns("/**");
super.addInterceptors(registry);
}
/**
* 跨域处理 映射所有路径 允许所有来源 以下方法请求
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH");
}
七:shiro权限配置
@Configurationpublic class ShiroConfig implements EnvironmentAware {private final static int REMEMBER_ME_MAX_AGE = 365 * 24 * 3600;// 这是个DestructionAwareBeanPostProcessor的子类,负责org.apache.shiro.util.Initializable类型bean的生命周期的,
// 初始化和销毁。主要是AuthorizingRealm类的子类,以及EhCacheManager类
@Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();}@Beanpublic SimpleCookie rememberMeCookie(){
SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
simpleCookie.setMaxAge(REMEMBER_ME_MAX_AGE);return simpleCookie;}@Beanpublic CookieRememberMeManager rememberMeManager(){
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();cookieRememberMeManager.setCookie(rememberMeCookie());//rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)
cookieRememberMeManager.setCipherKey(Base64.decode("2AvVhdsgUs0FSA3SDFAdag=="));
return cookieRememberMeManager;}// 为了对密码进行编码的,防止密码在数据库里明码保存,当然在登陆认证,这个类也负责对form里输入的密码进行编码。
@Bean(name = "hashedCredentialsMatcher")
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher credentialsMatcher = new ComHashedCredentialsMatcher();credentialsMatcher.setHashAlgorithmName("MD5");//散列算法:这里使用MD5算法;credentialsMatcher.setHashIterations(1);//散列的次数,比如散列两次,相当于 md5(md5(""));
credentialsMatcher.setStoredCredentialsHexEncoded(true);//true时密码加密用的是Hex编码;false时用Base64编码
return credentialsMatcher;}// 增加缓存减少对数据库的查询压力
@Bean(name = "ehcacheManager")
public EhCacheManager getEhCacheManager() {
EhCacheManager em = new EhCacheManager();em.setCacheManagerConfigFile("classpath:ehcache-shiro.xml");
return em;}// 自定义的认证类,继承自AuthorizingRealm,负责用户的认证和权限的处理
@Bean(name = "shiroRealm")
public MyAuthorizingRealm shiroRealm() {
MyAuthorizingRealm realm = new MyAuthorizingRealm();realm.setCredentialsMatcher(hashedCredentialsMatcher());realm.setCachingEnabled(true);realm.setCacheManager(getEhCacheManager());return realm;}//权限管理,这个类组合了登陆,登出,权限,session的处理
@Bean(name = "securityManager")
public DefaultWebSecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();securityManager.setRealm(shiroRealm());securityManager.setCacheManager(getEhCacheManager());securityManager.setRememberMeManager(rememberMeManager());DefaultWebSessionManager defaultWebSessionManager = new DefaultWebSessionManager();defaultWebSessionManager.setGlobalSessionTimeout(Long.parseLong(environment.getProperty("session.timeout")));
securityManager.setSessionManager(defaultWebSessionManager);return securityManager;}// 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证 * 配置以下
// 两个bean(DefaultAdvisorAutoProxyCreator(可选)和AuthorizationAttributeSourceAdvisor)即可实现此功能
@Bean(name = "advisorAutoProxyCreator")
@DependsOn({"lifecycleBeanPostProcessor"})
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();advisorAutoProxyCreator.setProxyTargetClass(true);return advisorAutoProxyCreator;}@Bean(name = "authorizationAttributeSourceAdvisor")
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(){
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());return authorizationAttributeSourceAdvisor;}@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean shiroFilterFactoryBean() {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();shiroFilterFactoryBean.getFilters().put("comauth", new ComAuthFilter());
shiroFilterFactoryBean.setSecurityManager(securityManager());shiroFilterFactoryBean.setLoginUrl("/");
shiroFilterFactoryBean.setSuccessUrl("/index");
shiroFilterFactoryBean.setUnauthorizedUrl("/notlogin");
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();filterChainDefinitionMap.put("/", "user");filterChainDefinitionMap.put("/css/**", "anon");filterChainDefinitionMap.put("/js/**", "anon");filterChainDefinitionMap.put("/img/**", "anon");filterChainDefinitionMap.put("/", "anon");filterChainDefinitionMap.put("/**.html", "anon");filterChainDefinitionMap.put("/login", "anon");filterChainDefinitionMap.put("/login/checkcode", "anon");filterChainDefinitionMap.put("/login/notlogin", "anon");filterChainDefinitionMap.put("/export", "anon");filterChainDefinitionMap.put("/spiCalc", "anon");filterChainDefinitionMap.put("/hello/**", "anon"); //配置不控制权限请求 anonfilterChainDefinitionMap.put("/hellox", "anon");filterChainDefinitionMap.put("/", "anon");filterChainDefinitionMap.put("/**", "comauth");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);return shiroFilterFactoryBean;}private Environment environment;
@Overridepublic void setEnvironment(Environment environment) {
this.environment = environment;}}
八、Consul服务注册与发现
/**
* consul agent -server -bootstrap-expect=1 -data-dir=data -node=server0 -bind=127.0.0.1 -client 0.0.0.0 -ui* Created by windwant on 2016/8/18.*/@Componentpublic class ConsulMgr {private static final Logger logger = LoggerFactory.getLogger(ConsulMgr.class);@org.springframework.beans.factory.annotation.Value("${consul.host}")
private String consulHost;@org.springframework.beans.factory.annotation.Value("${server.port}")
private Integer port;
@org.springframework.beans.factory.annotation.Value("${redis.host}")
private String redisHost;@org.springframework.beans.factory.annotation.Value("${redis.port}")
private Integer redisPort;
private KeyValueClient keyValueClient;
private HealthClient healthClient;
private AgentClient agentClient;
private CatalogClient catalogClient;
private String redisService = "redis";private String bootService = "boot";public void init(){
Consul consul = Consul.builder().withConnectTimeoutMillis(3000).withPing(true).withReadTimeoutMillis(2000).withWriteTimeoutMillis(2000).withHostAndPort(HostAndPort.fromParts(consulHost, 8500)).build();keyValueClient = consul.keyValueClient();healthClient = consul.healthClient();agentClient = consul.agentClient();//注册本服务到consul
registerService(bootService, bootService, bootService, consulHost, port, 5);//注册测试redis服务
registerService(redisService, redisService, redisService, redisHost, redisPort, 5);//获取可用redis服务
getHealthService(redisService);//监控redis服务
watchSvrx();}/**
* 注册服务*/public void registerService(String svrId, String svrName, String tags, String host, Integer port, Integer interval){//健康检查
ImmutableRegCheck immutableRegCheck = ImmutableRegCheck.builder().tcp(host + ":" + port).interval(interval + "s").build();ImmutableRegistration immutableRegistration = ImmutableRegistration.builder().id(svrId).name(svrName).addTags(tags).address(host).port(port).addChecks(immutableRegCheck).build();agentClient.register(immutableRegistration);}/**
* 获取正常服务* @param serviceName*/public void getHealthService(String serviceName){List<ServiceHealth> nodes = healthClient.getHealthyServiceInstances(serviceName).getResponse();dealHealthSvr(nodes);}private void dealHealthSvr(List<ServiceHealth> services){
if(StringUtils.isNotBlank(JedisUtils.getHost()) && services.size() > 0) {
services.forEach((resp) -> {
if (StringUtils.equals(resp.getService().getAddress(), JedisUtils.getHost()) &&
resp.getService().getPort() == JedisUtils.getPort()) {if(JedisUtils.getJedisPool().isClosed()){
JedisUtils.init(resp.getService().getAddress(), resp.getService().getPort());return;}return;}});}if(StringUtils.isBlank(JedisUtils.getHost()) && services.size() > 0) {
services.forEach((resp) -> {
Service service = resp.getService();System.out.println("service port: " + service.getPort());
System.out.println("service address: " + service.getAddress());
//选取一个服务器初始化redis jedispool
if (JedisUtils.init(service.getAddress(), service.getPort())) {
return;}});}if(JedisUtils.getJedisPool() != null) {
//测试redis
JedisUtils.set("test key", "test value");JedisUtils.get("test key");//测试redis分布式锁
JedisUtils.setLockKey("test lock key", "test lock value", 3);JedisUtils.get("test lock key");}}//监控redis可用服务
ScheduledExecutorService scheduled = Executors.newSingleThreadScheduledExecutor();public void watchSvrx(){
scheduled.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {
getHealthService(redisService);}}, 0, 10, TimeUnit.SECONDS);}public void watchSvr(){
try {ServiceHealthCache serviceHealthCache = ServiceHealthCache.newCache(healthClient, redisService);serviceHealthCache.addListener(map -> {logger.info("ServiceHealthCache change event");
List<ServiceHealth> list = new ArrayList<ServiceHealth>();for (ServiceHealth serviceHealth : map.values()) {
list.add(serviceHealth);
}ConsulMgr.this.dealHealthSvr(list);});serviceHealthCache.start();} catch (Exception e) {logger.info("ServiceHealthCache e: {}", e);
}}}
九、reids分布式锁
public class JedisUtils {private static final Logger logger = LoggerFactory.getLogger(JedisUtils.class);//设置锁的lua脚本
private static final String SETNX_EXPIRE_SCRIPT = "if redis.call('setnx', KEYS[1], KEYS[2]) == 1 then\n"+ "return redis.call('expire', KEYS[1], KEYS[3]);\n" + "end\n" + "return nil;";private static JedisPool jedisPool;
public static JedisPool getJedisPool() {
return jedisPool;}public static void setJedisPool(JedisPool jedisPool) {
JedisUtils.jedisPool = jedisPool;}private static String host;private static Integer port;
public static String getHost() {return host;}public static void setHost(String host) {JedisUtils.host = host;}public static Integer getPort() {
return port;}public static void setPort(Integer port) {
JedisUtils.port = port;}public static boolean init(String host, Integer port){try {JedisUtils.host = host;JedisUtils.port = port;jedisPool = new JedisPool(host, port);System.out.println(jedisPool);return true;}catch (Exception e){}return false;}public static boolean checkExist(String key) {if(jedisPool == null) return false;
try (Jedis jedis = jedisPool.getResource()) {logger.info("get redis key record: {}", jedis.get(key));return jedis.exists(key);}catch (Exception e) {logger.warn("get redis key record failed , the message is " + e.getMessage());
}return false;}public static void set(String key, String value) {if(jedisPool == null) return;
try (Jedis jedis = jedisPool.getResource()) {logger.info("set key: {}, value: {}", key, value);
jedis.set(key, value);
jedis.expire(key, 20);}catch (Exception e) {logger.warn("set key failed , the message is " + e.getMessage());
}}public static String get(String key) {if(jedisPool == null) return null;
try (Jedis jedis = jedisPool.getResource()) {String value = jedis.get(key);logger.info("get key: {}, value: {}", key, value);
return value;}catch (Exception e) {logger.warn("get key failed , the message is " + e.getMessage());
}return null;}/**
* 设置锁的lua脚本* private static final String SETNX_EXPIRE_SCRIPT = "if redis.call('setnx', KEYS[1], KEYS[2]) == 1 then\n"* "return redis.call('expire', KEYS[1], KEYS[3]);\n" + "end\n" + "return nil;";** @param key* @return*/public static boolean setLockKey(String key, String value, Integer seconds) {if (jedisPool == null) return false;
try (Jedis jedis = jedisPool.getResource()) {if(jedis.eval(SETNX_EXPIRE_SCRIPT, 3, key, value, String.valueOf(seconds)) != null){logger.info("set lock key: {}, value: {}", key, value);
return true;}}catch (Exception e) {logger.warn("set lock key failed , the message is " + e.getMessage());
}return false;}}
十、SPI机制
参考:Java SPI机制
十一、static资源
配置个性化资源路径:
@Configurationpublic class WebMvcConfigurer extends WebMvcConfigurerAdapter {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/uploadImg/**").addResourceLocations("file:/data/share/plane_images/");super.addResourceHandlers(registry);}
十二、druid数据源
package org.windwant.spring.config;import com.alibaba.druid.support.http.StatViewServlet;import com.alibaba.druid.support.http.WebStatFilter;import com.alibaba.druid.support.spring.stat.BeanTypeAutoProxyCreator;import com.alibaba.druid.support.spring.stat.DruidStatInterceptor;import org.springframework.aop.framework.ProxyFactoryBean;import org.springframework.aop.support.DefaultPointcutAdvisor;import org.springframework.aop.support.JdkRegexpMethodPointcut;import org.springframework.boot.web.servlet.FilterRegistrationBean;import org.springframework.boot.web.servlet.ServletRegistrationBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.windwant.spring.service.BootService;import java.util.Arrays;/**
* Created by Administrator on 2018/2/6.*/@Configurationpublic class DruidConfig {/**
* 注册 StatViewServlet druid web页面使用* @return*/@Beanpublic ServletRegistrationBean druidServlet() {
ServletRegistrationBean reg = new ServletRegistrationBean();reg.setServlet(new StatViewServlet());reg.addUrlMappings("/druid/*");
return reg;}@Beanpublic FilterRegistrationBean druidWebStatFilter(){
FilterRegistrationBean reg = new FilterRegistrationBean();reg.setFilter(new WebStatFilter());reg.setUrlPatterns(Arrays.asList("/*"));
reg.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");reg.addInitParameter("sessionStatMaxCount", "1000");reg.addInitParameter("sessionStatEnable", "true");reg.addInitParameter("principalSessionName", "druid.user");reg.addInitParameter("profileEnable", "true");return reg;}/**
* Spring和Jdbc的关联监控。* DruidStatInterceptor:标准的Spring MethodInterceptor。可以灵活进行AOP配置* Advice* @return*/@Beanpublic DruidStatInterceptor interceptorNames(){
DruidStatInterceptor inc = new DruidStatInterceptor();return inc;}//=====================按类型拦截 配置Spring监控============================================
/**
* 按类型拦截配置* @return*/@Beanpublic BeanTypeAutoProxyCreator beanTypeAutoProxyCreator(){
BeanTypeAutoProxyCreator cut = new BeanTypeAutoProxyCreator();cut.setTargetBeanType(BootService.class);
cut.setInterceptorNames("interceptorNames");
return cut;}//=====================按方法名正则匹配拦截 配置Spring监控====================================
/**
* pointcut* @return*/@Beanpublic JdkRegexpMethodPointcut jdkRegexpMethodPointcut(){
JdkRegexpMethodPointcut cut = new JdkRegexpMethodPointcut();cut.setPatterns("org.windwant.spring.mapper.*");
return cut;}/**
* Advisor* @param pointcut* @param interceptor* @return*/@Beanpublic DefaultPointcutAdvisor defaultPointcutAdvisor(JdkRegexpMethodPointcut pointcut, DruidStatInterceptor interceptor){
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();advisor.setPointcut(pointcut);advisor.setAdvice(interceptor);return advisor;}/**
* AOP proxy based on beans in Spring* @return*/@Beanpublic ProxyFactoryBean proxyFactoryBean(){
ProxyFactoryBean proxy = new ProxyFactoryBean();proxy.setInterceptorNames("defaultPointcutAdvisor");
return proxy;}}
十三、dubbo rpc
<?xml version="1.0" encoding="UTF-8"?><beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns:context="http://www.springframework.org/schema/context"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:application.yml"/><dubbo:application name="${dubbo.application.name}" owner="boot-server"organization="windwant"/>
<dubbo:registry id="bootRegistry" address="${dubbo.registry.address}"/><dubbo:protocol port="${dubbo.protocal.port}" serialization="${dubbo.protocal.serialization}"dispatcher="all" optimizer="org.windwant.common.api.SerializationOptimizerImpl"threadpool="cached" threads="${dubbo.provider.threads}"/><dubbo:protocol id="publicApi" port="${dubbo.protocal.port}" serialization="${dubbo.protocal.serialization}"dispatcher="all" threadpool="cached" threads="${dubbo.provider.threads}"/><dubbo:provider timeout="${dubbo.provider.timeout}" filter="dubboCatFilter"proxy="${dubbo.provider.proxy}" retries="${dubbo.provider.retries}"/><dubbo:service interface="org.windwant.common.api.DubboService" ref="dubbosvr"registry="bootRegistry"/>
</beans>
。。。
Spring Boot 官网:https://projects.spring.io/spring-boot/