Spring Boot 基於註解式開發 maven REST 示例項目css
項目地址:https://github.com/windwant/spring-boot-servicehtml
項目地址:https://github.com/windwant/spring-dubbo-servicejava
項目特點:
1. servlet、listener、interceptor、filter配置node
2. mybatis配置集成,多數據源 RouingDataSourcemysql
3. 集成jmx監控 MBeangit
4. 定時任務配置 Scheduledgithub
5. aop配置web
6. ftp服務 FTPTranportredis
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 服務
1、 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方法。
@Configuration
public class ApplicationConfig {
@Configuration
public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new BootInterceptor()).addPathPatterns("/**");
super.addInterceptors(registry);
}
...
3. listenenr:實現各類listener
@WebListener
public class BootListener implements ServletContextListener {
...
2、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.Driver
type: org.apache.commons.dbcp.BasicDataSource
max-active: 30
max-idle: 10
max-wait: 10
test-while-idle: true
remote:
url: $[datasource.remote.url]
username: $[datasource.remote.user]
password: $[datasource.remote.password]
driverClassName: com.mysql.jdbc.Driver
type: org.apache.commons.dbcp.BasicDataSource
max-active: 30
max-idle: 10
max-wait: 10
test-while-idle: true
DataSource 註解配置:
/**
* Created by windwant on 2016/12/30.
* implements EnvironmentAware, ApplicationContextAware
*/
@Configuration
public 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)
@Lazy
public 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配置:
@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurerProxy mapperScannerConfigurerProxy = new MapperScannerConfigurerProxy();
mapperScannerConfigurerProxy.setBasePackage("org.windwant.spring.mapper");
return mapperScannerConfigurerProxy;
}
3、集成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;
@ManagedAttribute
public String getName() {
System.out.println("name: " + name);
return name;
}
@ManagedAttribute
public void setName(String name) {
this.name = name;
}
@ManagedAttribute
public int getAge() {
System.out.println("age: "+age);
return age;
}
@ManagedAttribute
public void setAge(int age) {
this.age = age;
}
@ManagedAttribute
public String getMessage() {
System.out.println("message: " + message);
return message;
}
@ManagedAttribute
public 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);
}
@Autowired
FTPTransport ftpTransport;
@ManagedOperation
public 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
@Component
public 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驗證提示信息:
@Bean
public 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權限配置
@Configuration
public 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();
}
@Bean
public SimpleCookie rememberMeCookie(){
SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
simpleCookie.setMaxAge(REMEMBER_ME_MAX_AGE);
return simpleCookie;
}
@Bean
public 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"); //配置不控制權限請求 anon
filterChainDefinitionMap.put("/hellox", "anon");
filterChainDefinitionMap.put("/", "anon");
filterChainDefinitionMap.put("/**", "comauth");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
private Environment environment;
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
}
8、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.
*/
@Component
public 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() {
@Override
public 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);
}
}
}
9、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;
}
}
10、SPI機制
參考:Java SPI機制
11、static資源
配置個性化資源路徑:
@Configuration
public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/uploadImg/**").addResourceLocations("file:/data/share/plane_images/");
super.addResourceHandlers(registry);
}
12、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.
*/
@Configuration
public class DruidConfig {
/**
* 註冊 StatViewServlet druid web頁面使用
* @return
*/
@Bean
public ServletRegistrationBean druidServlet() {
ServletRegistrationBean reg = new ServletRegistrationBean();
reg.setServlet(new StatViewServlet());
reg.addUrlMappings("/druid/*");
return reg;
}
@Bean
public 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
*/
@Bean
public DruidStatInterceptor interceptorNames(){
DruidStatInterceptor inc = new DruidStatInterceptor();
return inc;
}
//=====================按類型攔截 配置Spring監控============================================
/**
* 按類型攔截配置
* @return
*/
@Bean
public BeanTypeAutoProxyCreator beanTypeAutoProxyCreator(){
BeanTypeAutoProxyCreator cut = new BeanTypeAutoProxyCreator();
cut.setTargetBeanType(BootService.class);
cut.setInterceptorNames("interceptorNames");
return cut;
}
//=====================按方法名正則匹配攔截 配置Spring監控====================================
/**
* pointcut
* @return
*/
@Bean
public JdkRegexpMethodPointcut jdkRegexpMethodPointcut(){
JdkRegexpMethodPointcut cut = new JdkRegexpMethodPointcut();
cut.setPatterns("org.windwant.spring.mapper.*");
return cut;
}
/**
* Advisor
* @param pointcut
* @param interceptor
* @return
*/
@Bean
public 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
*/
@Bean
public ProxyFactoryBean proxyFactoryBean(){
ProxyFactoryBean proxy = new ProxyFactoryBean();
proxy.setInterceptorNames("defaultPointcutAdvisor");
return proxy;
}
}
十3、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/