一、简洁优美的代码
Spring的一个很大的优点是它非常简洁、优美的代码风格。其代码风格精简程度度比较高,因此非常容易上手,也非常容易读懂。它在代码的精简程度上非常注重,避免过度的冗余代码,使得代码看起来非常整洁。使用Spring框架,可以减少代码的复杂度,让代码更加简洁。
@Configuration @EnableWebMvc @ComponentScan(basePackages = "com.example.demo") public class AppConfig { @Bean public ViewResolver viewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); return resolver; } }
上面这段Spring代码使用了@Configuration注释使得这个类可以作为bean定义的来源,@EnableWebMvc注解会启用Spring MVC的支持,@ComponentScan是Spring自动扫描的注解,在包中搜索带有注释@Component、@Controller、@Service和@Repository。
二、IoC和DI容器
IoC(Inverse of Control)控制反转、DI(Dependency Injection)依赖注入是Spring框架的核心功能之一。借助它们,我们可以将对象与对象之间的依赖关系交由框架来管理,而不是由程序员自己去管理。这个特性可以让代码更加松耦合,避免了一些不必要的麻烦。同时,Spring的IoC和DI容器可以让我们更加方便而简单的管理应用程序中的任何对象和组件。
public class ArticleController { private ArticleService articleService; public ArticleController(ArticleService articleService) { this.articleService = articleService; } @RequestMapping("/articles") public ListgetArticles() { return articleService.getAllArticles(); } } @Service public class ArticleService { private ArticleRepository articleRepository; public ArticleService(ArticleRepository articleRepository) { this.articleRepository = articleRepository; } public List getAllArticles() { return articleRepository.getAllArticles(); } } @Repository public class ArticleRepositoryImpl implements ArticleRepository { public List getAllArticles() { //return a list of article objects from the database } }
上面是一个使用IoC和DI容器的例子,ArticleController的构造函数需要ArticleService实例作为参数,而ArticleService又需要ArticleRepository实例作为参数,这种依赖关系使得我们只需要在中心容器(BeanFactory)中注入ArticleRepository实例即可完成ArticleController、ArticleService的实例化。
三、AOP特性
AOP(Aspect Oriented Programming)面向切面编程是Spring框架的另一个核心功能。它是一个编程范式,可以将代码中的横切关注点进行模块化和复用。通过使用AOP,我们可以将一些通用的操作,如日志、安全、事务、缓存等关注点与核心业务逻辑相分离,从而使得代码更加简单、健壮和维护性更高。Spring框架提供了很多方便易用的AOP工具,比如@AspectJ注解,可以让你通过注释来定义切面。
@Aspect @Component public class LoggingAspect { private static final Logger LOGGER = LoggerFactory.getLogger(LoggingAspect.class); @Before("execution(public * com.example.demo.controller..*.*(..))") public void logBefore(JoinPoint joinPoint) { LOGGER.info("Calling method : " + joinPoint.getSignature().getName()); } @After("execution(public * com.example.demo.controller..*.*(..))") public void logAfter(JoinPoint joinPoint) { LOGGER.info("Called method : " + joinPoint.getSignature().getName()); } }
上面这段代码是一个AOP的例子,在这个例子中,我们定义了一个LoggingAspect类,使用了@Aspect注解告诉Spring这是一个切面,使用了@Before和@After注解,分别代表在指定的方法执行之前和之后执行切面方法,指定execution()表达式,则表示仅对应用程序中指定的所有控制器类的公共方法实施切面。
四、整合其他框架
Spring框架不仅仅是一个框架,它还是其他框架的搭配效果非常出色的整体解决方案。Spring框架整合了很多开源框架,如Hibernate、MyBatis、Struts等。通过整合其他框架,Spring更加易于使用和扩展。同时,Spring还提供了很多第三方开源整合插件,如Spring Batch、Spring Security等,使得整合其他框架更加便利,同时也为应用程序的开发人员提供了更好的扩展性和可用性。
@Configuration @EnableBatchProcessing public class BatchConfiguration { @Autowired public JobBuilderFactory jobBuilderFactory; @Autowired public StepBuilderFactory stepBuilderFactory; @Autowired public DataSource dataSource; @Bean public JdbcCursorItemReaderreader() { JdbcCursorItemReader reader = new JdbcCursorItemReader<>(); reader.setDataSource(dataSource); reader.setSql("SELECT id, firstName, lastName, birthdate FROM customer ORDER BY lastName, firstName"); reader.setRowMapper(new CustomerRowMapper()); return reader; } @Bean public CustomerItemProcessor processor() { return new CustomerItemProcessor(); } @Bean public JdbcBatchItemWriter writer() { JdbcBatchItemWriter writer = new JdbcBatchItemWriter<>(); writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>()); writer.setSql("INSERT INTO people (first_name, last_name, birthdate) VALUES (:firstName, :lastName, :birthdate)"); writer.setDataSource(dataSource); return writer; } @Bean public Job importUserJob(JobCompletionNotificationListener listener) { return jobBuilderFactory.get("importUserJob") .incrementer(new RunIdIncrementer()) .listener(listener) .flow(step1()) .end() .build(); } @Bean public Step step1() { return stepBuilderFactory.get("step1") . chunk(10) .reader(reader()) .processor(processor()) .writer(writer()) .build(); } }
上面这段代码就是Spring Batch框架的使用例子,通过@Configuration注解,我们可以将这个类当作一个配置类。通过@EnableBatchProcessing注解,启用 Spring Batch 的处理。Spring Batch 构建于 Spring 之上,因此我们使用 @Autowired 注解注入了 Spring 框架的 JobBuilderFactory、StepBuilderFactory 和 DataSource。这个类精简且用途明确,让 Spring Batch 的配置变得简单直观。