- Dependencias necesarias en pom.xml
Para habilitar el pool de conexiones Druid en un proyecto Spring Boot, incluya las siguientes dependencias en el archivo pom.xml.
<dependency>
<groupid>com.alibaba</groupid>
<artifactid>druid-spring-boot-starter</artifactid>
<version>1.1.14</version>
</dependency>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-data-jpa</artifactid>
</dependency>
<dependency>
<groupid>mysql</groupid>
<artifactid>mysql-connector-java</artifactid>
<version>8.0.21</version>
</dependency>
<dependency>
<groupid>org.springframework</groupid>
<artifactid>spring-jdbc</artifactid>
</dependency>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-configuration-processor</artifactid>
<optional>true</optional>
</dependency>
- Clase de configuración para el DataSource de Druid
Esta clase define un bean de DataSource que utiliza Druid, configurado mediante propiedades externas.
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.sql.SQLException;
@Configuration
public class ConfiguracionDruid {
@Autowired
private PropiedadesDataSource propiedades;
@Bean
@ConditionalOnMissingBean
public DataSource inicializarDataSource() {
DruidDataSource fuenteDatos = new DruidDataSource();
fuenteDatos.setDriverClassName(propiedades.getControlador());
fuenteDatos.setUrl(propiedades.getUrlConexion());
fuenteDatos.setUsername(propiedades.getUsuario());
fuenteDatos.setPassword(propiedades.getContrasena());
fuenteDatos.setInitialSize(propiedades.getTamanoInicial());
fuenteDatos.setMinIdle(propiedades.getMinimoConexionesInactivas());
fuenteDatos.setMaxActive(propiedades.getMaximoConexionesActivas());
fuenteDatos.setMaxWait(propiedades.getTiempoEsperaMaximo());
fuenteDatos.setTimeBetweenEvictionRunsMillis(propiedades.getIntervaloEviccion());
fuenteDatos.setMinEvictableIdleTimeMillis(propiedades.getTiempoMinimoEviccion());
fuenteDatos.setValidationQuery(propiedades.getConsultaValidacion());
fuenteDatos.setTestWhileIdle(propiedades.isProbarInactivo());
fuenteDatos.setTestOnBorrow(propiedades.isProbarAlObtener());
fuenteDatos.setTestOnReturn(propiedades.isProbarAlDevolver());
fuenteDatos.setPoolPreparedStatements(propiedades.isAgruparSentenciasPreparadas());
fuenteDatos.setMaxOpenPreparedStatements(propiedades.getMaximoSentenciasPreparadasAbiertas());
fuenteDatos.setMaxPoolPreparedStatementPerConnectionSize(propiedades.getMaximoSentenciasPorConexion());
try {
fuenteDatos.setFilters(propiedades.getFiltros());
fuenteDatos.init();
} catch (SQLException excepcion) {
excepcion.printStackTrace();
}
return fuenteDatos;
}
}
- Clase de propiedades para el DataSource
Esta clase carga la configuración de Druid desde el archivo application.yml, bajo el prefijo especificado.
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "spring.datasource.druid")
public class PropiedadesDataSource {
private String controlador;
private String urlConexion;
private String usuario;
private String contrasena;
private String filtros;
private int tamanoInicial;
private int minimoConexionesInactivas;
private int maximoConexionesActivas;
private long tiempoEsperaMaximo;
private long intervaloEviccion;
private long tiempoMinimoEviccion;
private String consultaValidacion;
private boolean probarInactivo;
private boolean probarAlObtener;
private boolean probarAlDevolver;
private boolean agruparSentenciasPreparadas;
private int maximoSentenciasPreparadasAbiertas;
private int maximoSentenciasPorConexion;
// Getters y setters para cada propiedad
public String getControlador() { return controlador; }
public void setControlador(String controlador) { this.controlador = controlador; }
public String getUrlConexion() { return urlConexion; }
public void setUrlConexion(String urlConexion) { this.urlConexion = urlConexion; }
public String getUsuario() { return usuario; }
public void setUsuario(String usuario) { this.usuario = usuario; }
public String getContrasena() { return contrasena; }
public void setContrasena(String contrasena) { this.contrasena = contrasena; }
public String getFiltros() { return filtros; }
public void setFiltros(String filtros) { this.filtros = filtros; }
public int getTamanoInicial() { return tamanoInicial; }
public void setTamanoInicial(int tamanoInicial) { this.tamanoInicial = tamanoInicial; }
public int getMinimoConexionesInactivas() { return minimoConexionesInactivas; }
public void setMinimoConexionesInactivas(int minimo) { this.minimoConexionesInactivas = minimo; }
public int getMaximoConexionesActivas() { return maximoConexionesActivas; }
public void setMaximoConexionesActivas(int maximo) { this.maximoConexionesActivas = maximo; }
public long getTiempoEsperaMaximo() { return tiempoEsperaMaximo; }
public void setTiempoEsperaMaximo(long tiempo) { this.tiempoEsperaMaximo = tiempo; }
public long getIntervaloEviccion() { return intervaloEviccion; }
public void setIntervaloEviccion(long intervalo) { this.intervaloEviccion = intervalo; }
public long getTiempoMinimoEviccion() { return tiempoMinimoEviccion; }
public void setTiempoMinimoEviccion(long tiempo) { this.tiempoMinimoEviccion = tiempo; }
public String getConsultaValidacion() { return consultaValidacion; }
public void setConsultaValidacion(String consulta) { this.consultaValidacion = consulta; }
public boolean isProbarInactivo() { return probarInactivo; }
public void setProbarInactivo(boolean probar) { this.probarInactivo = probar; }
public boolean isProbarAlObtener() { return probarAlObtener; }
public void setProbarAlObtener(boolean probar) { this.probarAlObtener = probar; }
public boolean isProbarAlDevolver() { return probarAlDevolver; }
public void setProbarAlDevolver(boolean probar) { this.probarAlDevolver = probar; }
public boolean isAgruparSentenciasPreparadas() { return agruparSentenciasPreparadas; }
public void setAgruparSentenciasPreparadas(boolean agrupar) { this.agruparSentenciasPreparadas = agrupar; }
public int getMaximoSentenciasPreparadasAbiertas() { return maximoSentenciasPreparadasAbiertas; }
public void setMaximoSentenciasPreparadasAbiertas(int maximo) { this.maximoSentenciasPreparadasAbiertas = maximo; }
public int getMaximoSentenciasPorConexion() { return maximoSentenciasPorConexion; }
public void setMaximoSentenciasPorConexion(int maximo) { this.maximoSentenciasPorConexion = maximo; }
}
- Filtro para estadísticas web de Druid
Configura un filtro para interceptar solicitudes y recopilar estadísticas de monitoreo.
import com.alibaba.druid.support.http.WebStatFilter;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
@WebFilter(filterName = "filtroEstadisticasWebDruid",
urlPatterns = "/*",
initParams = {
@WebInitParam(name = "exclusions", value = "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*")
}
)
public class FiltroEstadisticasWebDruid extends WebStatFilter {
}
- Servlet para la vista de monitoreo
Configrua el servlet que sirve la interfaz de monitoreo de Druid.
import com.alibaba.druid.support.http.StatViewServlet;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
@WebServlet(urlPatterns = {"/druid/*"},
initParams = {
@WebInitParam(name = "loginUsername", value = "admin"),
@WebInitParam(name = "loginPassword", value = "admin"),
@WebInitParam(name = "allow", value = ""),
@WebInitParam(name = "deny", value = "192.169.1.111"),
@WebInitParam(name = "resetEnable", value = "true")
}
)
public class ServletVistaMonitorizacionDruid extends StatViewServlet {
}
- Eliminar publicidad en la página de monitoreo
Configura un filtro para quitar los anuncios predeterminados de la interfaz de Druid.
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
import com.alibaba.druid.util.Utils;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.*;
import java.io.IOException;
@Configuration
@ConditionalOnWebApplication
@AutoConfigureAfter(DruidDataSourceAutoConfigure.class)
@ConditionalOnProperty(name = "spring.datasource.druid.stat-view-servlet.enabled", havingValue = "true", matchIfMissing = true)
public class ConfiguracionEliminarPublicidad {
@Bean
public FilterRegistrationBean registroFiltroEliminarPublicidad(DruidStatProperties propiedades) {
DruidStatProperties.StatViewServlet configuracionDruid = propiedades.getStatViewServlet();
String patron = configuracionDruid.getUrlPattern() != null ? configuracionDruid.getUrlPattern() : "/druid/*";
String patronJsComun = patron.replaceAll("\\*", "js/common.js");
final String rutaArchivo = "support/http/resources/js/common.js";
Filter filtro = new Filter() {
@Override
public void init(FilterConfig configuracionFiltro) {}
@Override
public void doFilter(ServletRequest solicitud, ServletResponse respuesta, FilterChain cadena) throws IOException, ServletException {
cadena.doFilter(solicitud, respuesta);
respuesta.resetBuffer();
String contenido = Utils.readFromResource(rutaArchivo);
contenido = contenido.replaceAll("<a.><br></br>", "");
contenido = contenido.replaceAll("powered.*?shrek.wang", "");
respuesta.getWriter().write(contenido);
}
@Override
public void destroy() {}
};
FilterRegistrationBean beanRegistro = new FilterRegistrationBean();
beanRegistro.setFilter(filtro);
beanRegistro.addUrlPatterns(patronJsComun);
return beanRegistro;
}
}
</a.>
- Clase principal de la aplicación
Agregue la anotación @ServletComponentScan para detectar los componentes de servlet definidos.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
@ServletComponentScan
public class AplicacionPrincipal {
public static void main(String[] argumentos) {
SpringApplication.run(AplicacionPrincipal.class, argumentos);
}
}
- Archivos de configuración
Defina la configuración en application.yml y un perfil específico para Druid.
# Archivo: application.yml
spring:
application:
name: aplicacion-principal
profiles:
active: druid
# Archivo: application-druid.yml
server:
port: 8083
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
name: fuenteDatosDruid
druid:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://host:puerto/base_datos?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
username: usuario
password: contrasena
filters: stat,wall,config
maxActive: 100
initialSize: 1
maxWait: 60000
minIdle: 1
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: select 'x'
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxOpenPreparedStatements: 50
maxPoolPreparedStatementPerConnectionSize: 20