XML 配置雖解耦但缺乏編譯期檢查,純註解又侵入業務代碼。Java Config(Spring 3.0+) 完美結合兩者優勢:類型安全、重構友好、IDE 智能提示、邏輯可編程,成為現代 Spring 應用首選配置方式。
src/main/java
├── config
│ ├── WebInitializer.java // Servlet 3.0+ 容器啟動入口
│ ├── WebConfig.java // SpringMVC Web 層配置
│ ├── RootConfig.java // 業務層、數據層配置
│ └── HibernateConfig.java // Hibernate 會話工廠配置
├── entity
│ └── User.java // JPA 實體
├── service
│ └── UserService.java
└── web
└── UserController.java
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override protected Class>[] getRootConfigClasses() { return new Class>[]{ RootConfig.class }; }
@Override protected Class>[] getServletConfigClasses() { return new Class>[]{ WebConfig.class }; }
@Override protected String[] getServletMappings() { return new String[]{ "/" }; }
@Override protected void customizeRegistration(Dynamic registration) {
registration.setMultipartConfig(new MultipartConfigElement("/temp", 2097152, 4194304, 0));
}
}
AbstractAnnotationConfigDispatcherServletInitializer 自動實現 WebApplicationInitializer,Servlet 3.0+ 容器啟動時自動發現並初始化。getRootConfigClasses 對應 ContextLoaderListener 加載的根上下文(Service、DAO、數據源)。getServletConfigClasses 對應 DispatcherServlet 加載的 Web 上下文(Controller、ViewResolver、HandlerMapping)。@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "scau.zzf.web", useDefaultFilters = false,
includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, value = Controller.class))
public class WebConfig extends WebMvcConfigurerAdapter {
@Bean public ViewResolver viewResolver() {
InternalResourceViewResolver r = new InternalResourceViewResolver();
r.setPrefix("/WEB-INF/views/"); r.setSuffix(".jsp");
r.setExposeContextBeansAsAttributes(true); return r;
}
@Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable(); // 靜態資源轉發給容器默認 Servlet
}
}
@Configuration
@Import(HibernateConfig.class)
@ComponentScan(basePackages = "scau.zzf",
excludeFilters = @ComponentScan.Filter(type = FilterType.CUSTOM, value = RootConfig.WebPackage.class))
public class RootConfig {
public static class WebPackage extends RegexPatternTypeFilter {
public WebPackage() { super(Pattern.compile("scau\\.zzf\\.web")); }
}
}
掃描除 web 包外的所有組件(@Service、@Repository、@Component),避免與 WebConfig 重複掃描 Controller。
@Configuration
@PropertySource("classpath:ds/ds-jdbc.properties")
public class HibernateConfig {
@Value("${jdbc.driverClassName}") private String driver;
@Value("${jdbc.url}") private String url;
@Value("${jdbc.username}") private String user;
@Value("${jdbc.password}") private String pass;
@Bean public DataSource dataSource() {
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName(driver); ds.setUrl(url);
ds.setUsername(user); ds.setPassword(pass);
return ds;
}
@Bean public SessionFactory sessionFactoryBean() throws IOException {
LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean();
lsfb.setDataSource(dataSource());
lsfb.setPackagesToScan("scau.zzf.entity");
Properties props = new Properties();
props.setProperty("dialect", "org.hibernate.dialect.MySQLDialect");
lsfb.setHibernateProperties(props);
lsfb.afterPropertiesSet();
return lsfb.getObject();
}
@Bean public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
return new PropertySourcesPlaceholderConfigurer(); // 解析 ${...} 佔位符
}
}
@Entity @Table(catalog = "hibernate", name = "users")
public class User {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id;
@Column private String username;
@Column private String password;
@Column private String sex;
@Column private String address;
@Column private int enabled;
// getter/setter 省略
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {WebConfig.class, RootConfig.class})
@WebAppConfiguration
public class ServiceTest {
@Autowired private UserService userService;
@Test public void userServiceTest() {
User u = userService.findUser(1);
System.out.println(u.getUsername());
}
}
@RunWith 整合 Spring Test、@ContextConfiguration 指定配置類、@WebAppConfiguration 模擬 ServletContext。@Profile、動態屬性注入、複雜 Bean 初始化邏輯皆可用 Java 代碼實現。WebInitializer 完全替代 web.xml,適配雲原生容器化部署。