Spring基础配置
Spring框架本身的四大原则:
- 使用POJO进行轻量级和最小侵入式开发。
- 通过依赖注入和基于接口编程实现松耦合。
- 通过AOP和默认习惯进行声明式编程。
- 使用AOP和模板(template)减少模式化代码。
Spring的依赖注入
1. 基础知识
控制翻转(Inversion of Control-IOC)和依赖注入(dependency injection-DI)在Spring环境下是等同的概念,控制翻转是通过依赖注入实现的。
所谓的依赖注入指的是容器负责创建对象和维护对象间的依赖关系,依赖注入的主要目的就是为了解耦,体现了一种“组合”的理念。
Spring IoC容器(ApplicationContext)负责创建Bean,并通过容器将功能类Bean注入到所需要的Bean中。Spring提供使用xml、注解、Java配置、groovy配置实现Bean的创建和注入。
无论是xml配置、注解配置还是Java配置,都被称为配置元数据,所谓元数据即描述数据的数据。元数据本身不具备任何可执行的能力,只能通过外界代码来对这些元数据进行解析后进行一些有意义的操作。Spring容器解析这些配置元数据进行Bean初始化、配置和管理依赖。
声明Bean的注解:
- @Component组件,没有明确的角色。
- @Service 在业务逻辑层(Service层)使用。
- @Repository 在数据访问层(dao层)使用。
- @Controller 在展现层(MVC—>SpringMVC)使用。
注入Bean的注解:
- @Autowired:Spring提供的注解。
2. 示例
(1)编写功能类Bean。
import org.springframework.stereotype.Service;
@Service //1
public class FunctionService {
public String sayHello(String word) {
return "Hello" + word + "!";
}
}
代码解释
注解①:使用@Service注解声明当前FunctionService类是Spring管理的一个Bean。其中使用@Component、@Service、@Repository和@Controller是等效的,可根据需要选用。
(2)使用功能类的Bean
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service //1
public class UseFunctionService {
@Autowired //2
FunctionService functionService;
public String sayHello(String word) {
return functionService.sayHello(word);
}
}
代码解释
注解①:使用@Service注解声明当前UseFunctionService类是Spring管理的一个Bean;
注解②:使用@Autowired将FunctionService的实体Bean注入到UseFunctionService中,让UseFunctionService具备FunctionService的功能。
(3)配置类
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration //1
@ComponentScan("test") //2
public class DiConfig {
}
代码解释
注解①:@Configuration声明当前类是一个配置类;
注解②:使用@ComponentScan,自动扫描包下所有使用@Service、@Component、@Repository和@Controller的类,并注册为Bean。
Java配置
1. 基础知识
Java配置是通过@Configuration和@Bean来实现的。
- @Configuration 声明当前类是一个配置类,相当于一个Spring配置的xml文件。
- @Bean 注解在方法上,声明当前方法的返回值为一个Bean。
主要的原则是:全局配置使用Java配置(如数据库相关配置、MVC相关配置),业务Bean的配置使用注解配置(@Service、@Component、@Repository、@Controller)。
2. 示例
(1)编写功能类的Bean。
public class FunctionService {
public String sayHello(String word) {
return "Hello" + word + "!";
}
}
(2) 使用功能类的Bean。
public class UseFunctionService {
FunctionService functionService;
public void setFunctionService(FunctionService functionService) {
this.functionService = functionService;
}
public String sayHello(String word) {
return functionService.sayHello(word);
}
}
(3) 配置类。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration //1
public class JavaConfig {
@Bean //2
public FunctionService functionService() {
return new FunctionService();
}
@Bean
public UseFunctionService useFunctionService() {
UseFunctionService useFunctionService = new UseFunctionService();
useFunctionService.setFunctionService(functionService());//3
return useFunctionService;
}
// @Bean
//4
// public UseFunctionService useFunctionService(FunctionService functionService) {
// UseFunctionService useFunctionService = new UseFunctionService();
// useFunctionService.setFunctionService(functionService);
// return useFunctionService;
}
}
代码解释
注释①:使用@Configuration 注解表明当前类是一个配置类,这意味着这个类里可能有0个或者多个@Bean注解,此处没用使用包扫描,是因为所有的Bean都在此类中定义了。
注释②:使用@Bean注解声明当前方法FuncionService的返回值是一个Bean,Bean的名称是方法名。
注释③:注入FunctionService的Bean时候直接调用functionService().
注释④:另外一种注入方式,直接将FunctionService作为参数给useFunctionService(),这也是Sping容器提供的极好的功能。在Spring容器中,只要容器中存在某个Bean,就可以在另外一个Bean的声明方法的参数中注入。
AOP
基础知识
AOP:面向切面编程,相对于OOP面向对象编程。
Spring的AOP存在的目的是为了解耦。AOP可以让一组类共享相同的行为。在OOP只能通过继承类和实现接口,来使代码的耦合度增强,且类继承只能为单继承,阻碍更多行为添加到一组类上,AOP弥补了OOP的不足。
Spring支持AspectJ的注解式切面编程。
(1)使用@Aspect声明是一个切面。
(2)使用@After、@Before、@Around定义建言(advice),可直接将拦截规则(切点)作为参数。
(3)其中@After、@Before、@Around参数的拦截规则为切点(PointCut),为了使切点复用,可使用@PointCut专门定义拦截规则,然后在@After、@Before、@Around的参数中调用。
(4)其中符合条件的每一个被拦截处为连接点(JoinPoint)。