文章目录
1. 企业级应用概述
企业级应用开发需要考虑更多的因素,包括可扩展性、可维护性、安全性、性能、监控等。Spring Boot为企业级应用开发提供了完整的解决方案。
1.1 企业级应用特点
- 高可用性:7x24小时稳定运行
- 高性能:支持高并发和大数据量处理
- 可扩展性:支持水平扩展和垂直扩展
- 安全性:完善的安全机制和权限控制
- 可维护性:清晰的架构和代码规范
- 监控运维:完善的监控和运维体系
1.2 企业级架构
- 分层架构:表现层、业务层、数据层
- 微服务架构:服务拆分、服务治理、服务监控
- 领域驱动设计:业务建模、领域服务、聚合根
- 事件驱动架构:异步处理、事件溯源、CQRS
1.3 核心依赖
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Spring Boot Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Spring Boot Cache -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- Spring Boot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Spring Boot Validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
2. 企业级架构设计
2.1 分层架构
package com.example.demo.architecture;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@ComponentScan(basePackages = {
"com.example.demo.controller",
"com.example.demo.service",
"com.example.demo.repository",
"com.example.demo.config"
})
@EnableAspectJAutoProxy
public class EnterpriseArchitectureConfig {
@Bean
public ApplicationContextAware applicationContextAware() {
return new ApplicationContextAware();
}
}
2.2 领域驱动设计
package com.example.demo.domain;
import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
// 聚合根
@Entity
@Table(name = "orders")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String orderNumber;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private OrderStatus status;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<OrderItem> items = new ArrayList<>();
@Column(name = "created_at", nullable = false)
private LocalDateTime createdAt;
@Column(name = "updated_at")
private LocalDateTime updatedAt;
// 业务方法
public void addItem(OrderItem item) {
if (status != OrderStatus.DRAFT) {
throw new IllegalStateException("只能向草稿订单添加商品");
}
item.setOrder(this);
items.add(item);
}
public void confirm() {
if (status != OrderStatus.DRAFT) {
throw new IllegalStateException("只能确认草稿订单");
}
if (items.isEmpty()) {
throw new IllegalStateException("订单必须包含商品");
}
status = OrderStatus.CONFIRMED;
updatedAt = LocalDateTime.now();
}
public void cancel() {
if (status == OrderStatus.SHIPPED || status == OrderStatus.DELIVERED) {
throw new IllegalStateException("已发货或已送达的订单不能取消");
}
status = OrderStatus.CANCELLED;
updatedAt = LocalDateTime.now();
}
// 枚举
public enum OrderStatus {
DRAFT, CONFIRMED, PAID, SHIPPED, DELIVERED, CANCELLED
}
// 构造方法、getter和setter方法
public Order() {}
public Order(String orderNumber) {
this.orderNumber = orderNumber;
this.status = OrderStatus.DRAFT;
this.createdAt = LocalDateTime.now();
}
// getter和setter方法
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getOrderNumber() { return orderNumber; }
public void setOrderNumber(String orderNumber) { this.orderNumber = orderNumber; }
public OrderStatus getStatus() { return status; }
public void setStatus(OrderStatus status) { this.status = status; }
public List<OrderItem> getItems() { return items; }
public void setItems(List<OrderItem> items) { this.items = items; }
public LocalDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
public LocalDateTime getUpdatedAt() { return updatedAt; }
public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; }
}
2.3 领域服务
package com.example.demo.domain.service;
import com.example.demo.domain.Order;
import com.example.demo.domain.OrderItem;
import com.example.demo.repository.OrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@Transactional
public class OrderDomainService {
@Autowired
private OrderRepository orderRepository;
// 创建订单
public Order createOrder(String orderNumber) {
Order order = new Order(orderNumber);
return orderRepository.save(order);
}
// 添加商品到订单
public void addItemToOrder(Long orderId, OrderItem item) {
Order order = orderRepository.findById(orderId)
.orElseThrow(() -> new RuntimeException("订单不存在"));
order.addItem(item);
orderRepository.save(order);
}
// 确认订单
public void confirmOrder(Long orderId) {
Order order = orderRepository.findById(orderId)
.orElseThrow(() -> new RuntimeException("订单不存在"));
order.confirm();
orderRepository.save(order);
}
// 取消订单
public void cancelOrder(Long orderId) {
Order order = orderRepository.findById(orderId)
.orElseThrow(() -> new RuntimeException("订单不存在"));
order.cancel();
orderRepository.save(order);
}
// 查询用户订单
public List<Order> getUserOrders(Long userId) {
return orderRepository.findByUserId(userId);
}
}
3. 企业级安全
3.1 安全配置
package com.example.demo.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
public class EnterpriseSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/api/public/**").permitAll()
.antMatchers("/api/admin/**").hasRole("ADMIN")
.antMatchers("/api/user/**").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated()
.and()
.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public JwtAuthenticationFilter jwtAuthenticationFilter() {
return new JwtAuthenticationFilter();
}
}
3.2 权限控制
package com.example.demo.security;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class SecureBusinessService {
// 基于角色的权限控制
@PreAuthorize("hasRole('ADMIN')")
public void adminOnlyOperation() {
// 只有管理员可以执行的操作
}
// 基于表达式的权限控制
@PreAuthorize("hasRole('USER') and #userId == authentication.principal.id")
public void userSpecificOperation(Long userId) {
// 用户只能操作自己的数据
}
// 基于方法的权限控制
@PreAuthorize("hasPermission(#orderId, 'Order', 'READ')")
public Order getOrder(Long orderId) {
// 基于权限的订单查询
return null;
}
// 基于数据的权限控制
@PreAuthorize("hasRole('ADMIN') or @orderService.isOwner(#orderId, authentication.principal.id)")
public void updateOrder(Long orderId, Order order) {
// 管理员或订单所有者可以更新订单
}
}
4. 企业级数据管理
4.1 多数据源配置
package com.example.demo.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
@EnableJpaRepositories(
basePackages = "com.example.demo.repository.primary",
entityManagerFactoryRef = "primaryEntityManagerFactory",
transactionManagerRef = "primaryTransactionManager"
)
public class PrimaryDataSourceConfig {
@Primary
@Bean(name = "primaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Bean(name = "primaryEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory(
@Qualifier("primaryDataSource") DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
em.setPackagesToScan("com.example.demo.entity.primary");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "update");
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL8Dialect");
properties.setProperty("hibernate.show_sql", "false");
em.setJpaProperties(properties);
return em;
}
@Primary
@Bean(name = "primaryTransactionManager")
public PlatformTransactionManager primaryTransactionManager(
@Qualifier("primaryEntityManagerFactory") LocalContainerEntityManagerFactoryBean entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory.getObject());
}
}
4.2 事务管理
package com.example.demo.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Isolation;
@Service
@Transactional
public class EnterpriseTransactionService {
@Autowired
private OrderRepository orderRepository;
@Autowired
private UserRepository userRepository;
// 只读事务
@Transactional(readOnly = true)
public Order getOrder(Long orderId) {
return orderRepository.findById(orderId).orElse(null);
}
// 写事务
@Transactional
public Order createOrder(Order order) {
return orderRepository.save(order);
}
// 新事务
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void logOrderCreation(Long orderId) {
// 记录订单创建日志,使用新事务确保日志记录成功
}
// 嵌套事务
@Transactional(propagation = Propagation.NESTED)
public void updateOrderItems(Long orderId, List<OrderItem> items) {
// 更新订单商品,使用嵌套事务
}
// 隔离级别控制
@Transactional(isolation = Isolation.READ_COMMITTED)
public void updateOrderStatus(Long orderId, OrderStatus status) {
// 使用读已提交隔离级别
}
}
5. 企业级缓存
5.1 分布式缓存
package com.example.demo.cache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
@Service
public class EnterpriseCacheService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// 缓存用户信息
@Cacheable(value = "users", key = "#id")
public User getUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
// 更新缓存
@CachePut(value = "users", key = "#user.id")
public User updateUser(User user) {
return userRepository.save(user);
}
// 清除缓存
@CacheEvict(value = "users", key = "#id")
public void deleteUser(Long id) {
userRepository.deleteById(id);
}
// 分布式锁
public boolean acquireLock(String lockKey, String lockValue, long expireTime) {
Boolean success = redisTemplate.opsForValue()
.setIfAbsent(lockKey, lockValue, expireTime, TimeUnit.SECONDS);
return success != null && success;
}
// 释放锁
public void releaseLock(String lockKey, String lockValue) {
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
"return redis.call('del', KEYS[1]) else return 0 end";
redisTemplate.execute(script, Collections.singletonList(lockKey), lockValue);
}
}
5.2 缓存策略
package com.example.demo.cache;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CacheStrategyService {
// 缓存预热
@Cacheable(value = "hotData")
public List<String> getHotData() {
return getDataFromDatabase();
}
// 缓存更新策略
@Caching(
evict = {
@CacheEvict(value = "users", key = "#user.id"),
@CacheEvict(value = "userList", allEntries = true)
}
)
public User updateUser(User user) {
return userRepository.save(user);
}
// 缓存穿透防护
@Cacheable(value = "users", key = "#id", unless = "#result == null")
public User getUserById(Long id) {
User user = userRepository.findById(id).orElse(null);
if (user == null) {
// 缓存空值,防止缓存穿透
return new User();
}
return user;
}
private List<String> getDataFromDatabase() {
// 从数据库获取数据
return null;
}
}
6. 企业级监控
6.1 监控配置
# application.yml
management:
endpoints:
web:
exposure:
include: "*"
base-path: /actuator
endpoint:
health:
show-details: always
show-components: always
info:
enabled: true
health:
defaults:
enabled: true
diskspace:
threshold: 100MB
db:
enabled: true
metrics:
export:
prometheus:
enabled: true
distribution:
percentiles-histogram:
http.server.requests: true
percentiles:
http.server.requests: 0.5, 0.95, 0.99
6.2 自定义监控
package com.example.demo.monitoring;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.concurrent.atomic.AtomicLong;
@Component
public class EnterpriseMonitor {
private final Counter businessCounter;
private final Timer businessTimer;
private final AtomicLong activeUsers;
@Autowired
public EnterpriseMonitor(MeterRegistry meterRegistry) {
this.businessCounter = Counter.builder("business.operations")
.description("Business operations count")
.register(meterRegistry);
this.businessTimer = Timer.builder("business.processing.time")
.description("Business processing time")
.register(meterRegistry);
this.activeUsers = meterRegistry.gauge("business.active.users", new AtomicLong(0));
}
public void recordBusinessOperation() {
businessCounter.increment();
}
public void recordProcessingTime(Runnable operation) {
businessTimer.record(operation);
}
public void setActiveUsers(long count) {
activeUsers.set(count);
}
}
7. 企业级部署
7.1 Docker配置
FROM openjdk:17-jdk-slim
WORKDIR /app
COPY target/enterprise-app-1.0.0.jar app.jar
EXPOSE 8080
ENV JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC"
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
7.2 Kubernetes配置
apiVersion: apps/v1
kind: Deployment
metadata:
name: enterprise-app
spec:
replicas: 3
selector:
matchLabels:
app: enterprise-app
template:
metadata:
labels:
app: enterprise-app
spec:
containers:
- name: enterprise-app
image: enterprise-app:latest
ports:
- containerPort: 8080
env:
- name: SPRING_PROFILES_ACTIVE
value: "prod"
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: enterprise-app-service
spec:
selector:
app: enterprise-app
ports:
- port: 80
targetPort: 8080
type: LoadBalancer
8. 企业级最佳实践
8.1 代码规范
package com.example.demo.bestpractice;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
@Service
@Transactional
public class EnterpriseBestPracticeService {
// 1. 使用Optional处理空值
public Optional<User> findUserById(Long id) {
return userRepository.findById(id);
}
// 2. 使用Builder模式构建复杂对象
public Order createOrder(OrderBuilder builder) {
return builder
.setOrderNumber(generateOrderNumber())
.setStatus(OrderStatus.DRAFT)
.setCreatedAt(LocalDateTime.now())
.build();
}
// 3. 使用策略模式处理不同业务逻辑
public void processOrder(Order order, PaymentStrategy strategy) {
strategy.processPayment(order);
}
// 4. 使用事件驱动架构
@EventListener
public void handleOrderCreated(OrderCreatedEvent event) {
// 处理订单创建事件
}
// 5. 使用AOP处理横切关注点
@AuditLog
public void updateUser(User user) {
userRepository.save(user);
}
}
8.2 配置管理
# application.yml
spring:
application:
name: enterprise-app
profiles:
active: ${SPRING_PROFILES_ACTIVE:dev}
datasource:
url: ${DB_URL:jdbc:mysql://localhost:3306/enterprise}
username: ${DB_USERNAME:root}
password: ${DB_PASSWORD:password}
hikari:
maximum-pool-size: ${DB_MAX_POOL_SIZE:20}
minimum-idle: ${DB_MIN_IDLE:5}
cache:
type: ${CACHE_TYPE:redis}
redis:
time-to-live: ${CACHE_TTL:600000}
security:
jwt:
secret: ${JWT_SECRET:mySecretKey}
expiration: ${JWT_EXPIRATION:86400}
server:
port: ${SERVER_PORT:8080}
servlet:
context-path: ${CONTEXT_PATH:/api}
logging:
level:
root: ${LOG_LEVEL:INFO}
com.example.demo: ${APP_LOG_LEVEL:DEBUG}
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
9. 总结
Spring Boot企业级应用开发需要综合考虑多个方面:
- 架构设计:分层架构、领域驱动设计、微服务架构
- 安全机制:认证授权、权限控制、数据安全
- 数据管理:多数据源、事务管理、数据一致性
- 缓存策略:分布式缓存、缓存一致性、缓存性能
- 监控运维:应用监控、性能监控、日志监控
- 部署运维:容器化部署、Kubernetes编排、自动化运维
- 最佳实践:代码规范、配置管理、性能优化
通过系统性的企业级应用开发,可以构建出高质量、高性能、高可用的Spring Boot应用。
1443

被折叠的 条评论
为什么被折叠?



