作为复习把,来一次总结,方便以后SpringBoot的翻看
1.导入组件
@Component:普通组件
@Service:service层
@Repository:dao层
@Controller:controller层(默认id为类名的小写驼峰)
@Import:快速导入外部组件(默认id为全限定类名)
@ImportResource(locations = {"classpath:application.xml"}):将以前的xml配置文件读取并应用
FactoryBean:实现接口,用@Bean导入容器,导入的是工厂产生的类
2.java配置类相关注解
@Configuration:声明为配置类
@Bean:返回值注册进容器
@ComponentScan:扫描注册组件
@WishlyConfiguration:@Configuration与@ComponentScan的组合注解
3.@Bean的属性支持
@Bean(initMethod = "",destroyMethod = "")
@Scope 设置Spring容器如何新建Bean实例(方法上,得有@Bean)
@Lazy:针对单例实现懒加载
@PostConstruct:由JSR-250提供,bean的initMethod
@PreDestory:由JSR-250提供,等价于bean的destroyMethod
4.注入bean的注解
@Autowired:由Spring提供,按类型装入
@Qualifier:指定组件id,而不是按照类型注入
@Primary:指定自动装配的首选
@Inject:由JSR-330提供
@Resource:由JSR-250提供,与@Autowired区别于按byName装入
5.@PropertySource和@Value注解
@Value("Howl")
String name;
@Value("#{systemProperties['os.name']}")
String osName;
@Value("#{ T(java.lang.Math).random() * 100 }")
String randomNumber;
@Value("#{domeClass.name}")
String name;
@Value("classpath:com/hgs/hello/test.txt")
String Resource file;
@Value("http://www.cznovel.com")
Resource url;
// 使用外部配置文件,前提把配置文件加载到环境变量中
Value("${book.name}")
String bookName;
@PropertySource 放在配置类上:读取properties外部配置文件K/V保存到运行的环境变量中,用${}取出
@PropertySource("classpath:com/hgs/hello/test/test.propertie")
6.切面(AOP)相关注解
@Aspect:声明一个切面类
@Before:前置通知
@After:后置通知
@AfterReturning:返回通知
@AfterThrowing:异常通知
@Around:在方法执行之前与之后执行
@PointCut:声明切点 在java配置类中使用@EnableAspectJAutoProxy注解开启Spring对AspectJ代理的支持(类上)
7.环境切换
@Profile:通过设定配置环境
@Conditional:实现Condition接口,从而决定该bean是否被实例化
8.异步相关
@EnableAsync:配置类中,通过此注解开启对异步任务的支持
@Async:在实际执行的bean方法使用该注解来申明其是一个异步任务(方法上或类上所有的方法都将异步,需要@EnableAsync开启异步任务)
9.定时任务相关
@EnableScheduling:在配置类上使用,开启计划任务的支持
@Scheduled:来申明这是一个任务,包括cron,fixDelay,fixRate等类型,使用cron表达式:每10秒执行
10.@Enable*注解说明
这些注解主要用来开启对xxx的支持。
@EnableAspectJAutoProxy:开启对AspectJ自动代理的支持
@EnableAsync:开启异步方法的支持
@EnableScheduling:开启计划任务的支持
@EnableWebMvc:开启Web MVC的配置支持
@EnableConfigurationProperties:开启对@ConfigurationProperties注解配置Bean的支持
@EnableJpaRepositories:开启对SpringData JPA Repository的支持
@EnableTransactionManagement:开启注解式事务的支持
@EnableCaching:开启注解式的缓存支持
11.测试相关注解
@RunWith:运行器,Spring中通常用于对JUnit的支持
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration:用来加载配置ApplicationContext,其中classes属性用来加载配置类
@ContextConfiguration(classes={TestConfig.class})
12.补充
@EventListener:添加监听器,当然要注册进容器
13.SpringMVC部分
@EnableWebMvc:在配置类中开启Web MVC的配置支持
@Controller:声明该类为SpringMVC中的Controller
@ResponseBody:响应返回字符串
@RestController:该注解为一个组合注解,相当于@Controller和@ResponseBody的组合
@RequestMapping:用于映射Web请求,包括访问路径和参数(类或方法上)
@GetMapping
@PostMapping
@RequestBody:请求发送json数据时,而参数在请求体中,而不是在url。那么该注解补充get方法只获取url参数的缺点,调用setter方法映射进对象中
@PathVariable:用于接收路径参数,resful风格
@CookieValue:放方法参数中,将映射到参数上
@RequestParam:绑定请求中name属性相同的变量(使用了反射)
@RestControllerAdvice
@ControllerAdvice:该注解将对于控制器的全局配置放置在同一个位置。注解了@Controller的类的方法可使用@ExceptionHandler、@InitBinder、@ModelAttribute注解到方法上, 这对所有注解了@RequestMapping的控制器内的方法有效。
结合下面的注解可实现:
@ExceptionHandler:用于全局处理控制器里的异常
@InitBinder:用来设置WebDataBinder,WebDataBinder用来自动绑定前台请求参数到Model中。
@ModelAttribute:本来的作用是绑定键值对到Model里,在@ControllerAdvice中是让全局的@RequestMapping都能获得在此处设置的键值对。
14.springboot注解
@SpringBootApplication
@EnableAutoConfiguration
@SpringBootConfiguration
@EnableConfigurationProperties:开启下面的功能
@ConfigurationProperties(prefix="person"):需要下面的依赖
其是@Value的升级版。注解类上,宽松批量注入属性,不像@Value一个个来书写注解
org.springframework.boot
spring-boot-configuration-processor
1. 组件注册
- 包扫描+组件注解:@Component
- @Bean:导入第三方包里面的组件
- @Import:快速给容器导入一个组件
- FactoryBean:实现接口注入容器
1.1 配置类上的基本注解
@Configuration:声明当前类为配置类
@Bean:声明方法的返回值为一个bean,id默认是方法名
@ComponentScan:用于对Component进行扫描,里面有包含与排除规则
@Configuration
@ComponentScan(value = {"com.howl.springannotation.controller","com.howl.springannotation.service"},
excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = Controller.class)
})
public class MainConfig {
@Bean(value = "person01")
public Person person(){
return new Person("Howl",20);
}
}
1.2 @Bean的属性
@Scope:设置Bean实例的作用域,默认单例(IOC容器启动会调用方法创建对象)
@Lazy:针对单实例实现懒加载
@Configuration
public class MainConfig2 {
@Bean
@Scope(value = "singleton")
@Lazy
public Person person(){
System.out.println("person was created");
return new Person("Howl",20);
}
}
1.3 @Conditional
满足条件才注册bean,其接收Condition类的数组。而Condition是个接口,需要我们去实现。
@Conditional可在方法上,也可在类上
public class MyCondition implements Condition {
/**
* @param context:判断条件能使用的上下文环境
* @param metadata:标注了@Conditional的注释信息
* 参数是使用该类的地方帮我们传进去的
* @return
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// context.getClassLoader();
// context.getBeanFactory();
// context.getClass();
// context.getRegistry();
// String os = context.getEnvironment().getProperty("os.name");
// return os.contains("Windows");
return false;
}
}
@Configuration
public class MainConfig {
@Bean
@Conditional({MyCondition.class})
public Person person01(){
return new Person("Howl",20);
}
}
1.4 Import、ImportSelector、Registrar、FactoryBean
- @Import(value = {Person.class,User.class}):直接写类,id默认全类名
- @Import(value = {MyImportSelector.class}):写ImportSelector实现类,id默认全类名
- @Import(value = {MyImportBeanDefinitionRegistrar.class}):手动注册bean
- FactoryBean:实现该接口,用@Bean注解导入该类,那么就会将其内部的类也加入容器。获取工厂可加前缀&
public class MyImportSelector implements ImportSelector {
/**
* @param importingClassMetadata:可获取注解类的所有注解信息
* @return:返回值就是要导入的组件
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.howl.springannotation.bean.Student","com.howl.springannotation.bean.Worker"};
}
}
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* @param importingClassMetadata:当前类的注解信息
* @param registry:BeanDefinition的注册类
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean teacher = registry.containsBeanDefinition("Teacher");
if (!teacher) {
RootBeanDefinition root = new RootBeanDefinition(Teacher.class);
registry.registerBeanDefinition("Teacher", root);
}
}
}
public class PersonFactoryBean implements FactoryBean {
// 返回一个对象会添加到容器中
@Override
public Person getObject() throws Exception {
return new Person();
}
@Override
public Class> getObjectType() {
return Person.class;
}
@Override
public boolean isSingleton() {
returnjava true;
}
}
@Configuration
@Import(value = {User.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MainConfig4 {
@Bean
public PersonFactoryBean personFactoryBean() {
return new PersonFactoryBean();
}
}
2. 属性赋值
- @Value:
- 基本数值
- SpEL #{}
- 配置文件 ${}
public class Person {
@Value("Howl")
private String name;
@Value("${person.age}")
private Integer age;
// 。。。。
}
@PropertySource(value = "classpath:person.properties")
@Configuration
public class MainConfig5 {
@Bean
public Person person(){
return new Person();
}
}
3. 自动装配
- @Autowired:用AutowiredAnnotationBeanPostProcssor完成自动注入的
- 放属性上
- 放setter(方法)上:调用方法完成赋值,方法的参数从容器中获取
- 放构造器上:默认的组件会调用无参构造器创建对象再进行初始化赋值等操作;若当前类只有一个有参构造器,那么@Autowired可以省略的(前提没有默认,否则首选默认)
- 配置@Bean,那么方法参数可以自动注入而不用@Autowired
- XXXAware:自定义组件想要使用Spring容器底层的组件(ApplicationContext,BeanFactory),只需实现接口即可,在创建对象的时候,会调用接口规定的方法。其实也是setter方法参数自动注入
@Autowired
BookService bookService;
@Autowired
public void setBookService(BookService bookService) {
this.bookService = bookService;
}
@Autowired
public BookController(BookService bookService) {
this.bookService = bookService;
}
@Bean
public BookController bookController(BookService bookService){
return new BookController(bookService);
}
4. 环境切换
默认是default标识,但是下面代码三步执行,第二部就是加载配置文件,没有设置环境,所以得手动做这三步
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MainConfig7.class)
public AnnotationConfigApplicationContext(Class>... componentClasses) {
this();
register(componentClasses); // 加载配置文件
refresh();
}
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
ac.getEnvironment().setActiveProfiles("dev");
ac.register(MainConfig7.class);
ac.refresh();
5. Bean生命周期
bean创建-----初始化-----销毁
一. 构造
- 单实例:容器启动时创建(调用构造器)
- 多实例:每次获取时创建(调用构造器)
二.初始化
- 对象创建完成,并复赋值好后,调用初始化方法
三.销毁
- 单实例:容器关闭时调用
- 多实例:容器不管理这个bean,GC来回收
指定初始化和销毁方法:
- @Bean(initMethod = "init",destroyMethod = "destory")
让Bean实现接口:
- InitializingBean
- DisposableBean
JSR-250提供注解
- @PostConstruct
- @PreDestroy
后置处理器:对每一个bean都有效
- BeanPostProcessor
public class Worker implements InitializingBean, DisposableBean {
public Worker() {
System.out.println("worker constructor");
}
@PostConstruct
public void init(){
System.out.println("worker init");
}
@PreDestroy
public void destory(){
System.out.println("worker destory");
}
@Override
public void destroy() throws Exception {
System.out.println("接口的销毁方法");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("接口的初始化方法");
}
}
public class MyBeanProcessor implements BeanPostProcessor {
/**
* @param bean:创建的实例
* @param beanName:实例的名字
* @return :返回需要用到的实例,类似于@Bean
* @throws BeansException
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(bean + beanName + "---------内容呢额-----------");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(bean + beanName + "-----------内容呢额---------");
return bean;
}
}
6. AOP
被切入的方法,切面类,各种通知、原理是动态代理
切面类:
@Aspect
public class LogAspect {
@AfterReturning(value = "execution(public void com.howl..*(..))", returning = "result")
public int after(JoinPoint joinPoint, Object result) {
System.out.println("前置通知" + joinPoint.getSignature().getName() + result);
return 10;
}
}
配置类:重点在于开启注解
@EnableAspectJAutoProxy // 开启切面注解
@Configuration
public class AopConfig {
@Bean // 注意Bean上的@Autowired是自动注入,可以不写的
public LogAspect logAspect(JoinPoint joinPoint){
return new LogAspect();
}
@Bean
public TestService testService(){
return new TestService();
}
}
7. 声明式事务
// 1. 导入相关依赖
// 2. 注册配置数据源
// 3. 给需要事务的方法或类标注@Transactional
// 4. 开启基于注解的事务管理功能 @EnableTransactionManagement
// 5. 注册Spring平台的事务管理器来控制事务,重点他要管理数据源,才能管理每一条连接,才能管理事务
@EnableTransactionManagement
@Configuration
public class DbConfig {
@Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUsername("root");
dataSource.setPassword("root");
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/test");
return dataSource;
}
// 可以放参数上,那样会自动注入Bean对象
// 或调用方法,配置类中的方法调用会被认为是依赖注入
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
return new DataSourceTransactionManager(dataSource());
}
}
8. 监听器
用在方法上,当然这个类要加入进容器才行
public class test {
@EventListener(classes = {ApplicationEvent.class})
public void evenListener(ApplicationEvent event){
System.out.println("注解下的监听器");
}
}
9. @ConfigurationProperties的使用
- 编写properties文件
- 编写properties类,类上加注解来宽松匹配
- 配置类上开启宽松匹配功能,并导入properties文件进环境
student.name=howl
student.age=20
@ConfigurationProperties(prefix = "student")
// @Component
public class StudentProperties {
private String name;
private int age;
// 利用setter方法注入
}
@EnableConfigurationProperties
@PropertySource("classpath:application.properties")
@Configuration
public class MainConfig10 {
@Bean
public Student student(){
return new Student();
}
}