目录
常用的注解有@Service:表示业务逻辑组件,@Repository:表示数据库组件
1. 查看IOC容器bean的name、@SpringBootApplication使用介绍
查看IOC容器bean的name:
- SpringApplication.run会返回IOC容器ConfigurableApplicationContext
- 然后通过ConfigurableApplicationContext.getBeanDefinitionNames返回IOC容器所有bean的name
@SpringBootApplication使用介绍:
- @SpringBootApplication的参数scanBasePackages会使默认的目录不被扫描,扫描新的目录
- @ComponentScan会使@SpringBootApplication的目录不被扫描,扫描新的目录
- @SpringBootApplication等同于@SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan
如下所示:
package com.hh.springbootTest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
// scanBasePackages会使默认的目录不被扫描,扫描新的目录
@SpringBootApplication(scanBasePackages = "com.hh.springbootTest")
// 会使@SpringBootApplication的目录不被扫描,扫描新的目录
@ComponentScan("com.hh")
// @SpringBootApplication等同于@SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan("com.hh.springbootTest")
public class MyApplication {
public static void main(String[] args) {
// 返回IOC容器
ConfigurableApplicationContext applicationContext =
SpringApplication.run(MyApplication.class, args);
// 查看IOC容器中的Bean对应的name
String[] beanNames = applicationContext.getBeanDefinitionNames();
for (String beanName : beanNames) {
System.out.println(beanName);
}
int beanCount = applicationContext.getBeanDefinitionCount();
}
}
运行程序,查看的所有bean的name如下:
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
......省略部分......
viewResolver // 进行文件上传的
......省略部分......
characterEncodingFilter // 进行字符编码的
......省略部分......
multipartResolver
spring.servlet.multipart-org.springframework.boot.autoconfigure.web.servlet.MultipartProperties
org.springframework.aop.config.internalAutoProxyCreator
2. 自定义SpringApplication
参数设置的优先级比application.properties低
方式一:通过new一个类得到对象的方式
package com.hh.springboottest;
import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootTestApplication {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(SpringBootTestApplication.class);
// 进行各种参数设置
springApplication.setBannerMode(Banner.Mode.OFF);
springApplication.run(args);
}
}
方式二:Builder方式。通过FluentAPI进行设置
package com.hh.springboottest;
import org.springframework.boot.Banner;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
@SpringBootApplication
public class SpringBootTestApplication {
public static void main(String[] args) {
new SpringApplicationBuilder()
.main(SpringBootTestApplication.class)
.sources(SpringBootTestApplication.class)
.bannerMode(Banner.Mode.OFF)
.run(args);
}
}
3. @Configuration注解
创建User类,如下所示:
package com.hh.springbootTest.myBean;
public class User {
private String name;
public User(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "User{" + "name='" + name + "'}";
}
}
@Configuration注解说明:
- 声明修饰的类是一个配置类,配置类也是IOC容器的一个组件
- proxyBeanMethods默认为true(Full),表示如果IOC容器有要获取的组件,则直接从IOC容器取, 实现单例功能。一般用于创建的对象之间有依赖
- proxyBeanMethods为false(Lite)则直接new一个,大部分场景使用,可以加速IOC容器启动
- 也可以在
@Bean注解说明:
- 表示向IOC容器添加name为userName1(默认是方法名),类型为User,值为User{name=‘user1’}的组件
- 也可以在方法上使用@Scope。如果类上定义了proxyBeanMethods为false,则@Scope失效
示例程序如下:
package com.hh.springbootTest.myConfig;
import com.hh.springbootTest.myBean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
// proxyBeanMethods:表示代理bean的方法
// 默认为true(Full),表示如果IOC容器有要获取的组件,则直接从IOC容器取, 实现单例功能。一般用于创建的对象之间有依赖
// false(Lite)则直接new一个,大部分场景使用,可以加速IOC容器启动
@Configuration(proxyBeanMethods = true) // 声明这是一个配置类,等同于一个配置文件。配置类本身也是组件
public class MyConfig {
@Scope("singleton") // 多实例对象prototype。默认是singleton
// 向IOC容器添加name为userName1(默认是方法名),类型为User,值为User{name='user1'}的组件
@Bean("userName1")
public User userName1() {
return new User("user1");
}
}
可以在主程序中,从IOC容器获取Bean对象,获取的方式有很多种,如下所示:
package com.hh.springbootTest;
import com.hh.springbootTest.myBean.User;
import com.hh.springbootTest.myConfig.MyConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
// 返回IOC容器
ConfigurableApplicationContext applicationContext =
SpringApplication.run(MyApplication.class, args);
// 通过IOC容器的组件name获取对象。Full模式下多次调用获取的是同一个对象
User user1 = applicationContext.getBean("userName1", User.class);
// 如果IOC容器有两个User类型的对象,则这里获取会报错
User user2 = applicationContext.getBean(User.class);
// 通过类class获取多个组件的name
String[] beanNames = applicationContext.getBeanNamesForType(User.class);
for(String beanName:beanNames) {
System.out.println(beanName); // 返回的结果是:userName1
}
// Full模式下通过MyConfig获取的User还是单例
MyConfig myConfig = applicationContext.getBean(MyConfig.class);
System.out.println(user2 == myConfig.userName1()); // 返回的结果是: true
}
}
4. @Import注解
@Import注解说明:
- 必须配合@Configuration注解使用,否则没有效果
- 向IOC容器中添加对应类型的组件。默认组件的名称就是全类名
- 只能添加无参构造器创建的组件
示例程序如下:
package com.hh.springbootTest.myConfig;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import java.util.ArrayList;
import java.util.HashMap;
// 必须配合@Configuration注解使用,否则没有效果
// 向IOC容器中添加对应类型的组件。默认组件的名称就是全类名
@Import({ArrayList.class, HashMap.class})
@Configuration
public class MyConfig {
}
很多功能开关,如@EnableAsync
,@EnableScheduling
,都是通过import来开启功能,添加需要的组件到IOC容器
5. @ImportResource注解
在旧的版本,我们通过编写XML文件,向IOC容器添加bean。为了使用以前编写的XML文件,可以通过@ImportResource注解对resources目录下的XML文件进行引用,就可以将bean添加到IOC容器。注意必须配合@Configuration注解使用,否则没有效果
User类,必须要有无参构造器,如下所示:
package com.hh.springbootTest.myBean;
public class User {
private String name;
public User() {
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "User{" + "name='" + name + "'}";
}
}
resouces/user.xml文件内容,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="userName1" class="com.hh.springbootTest.myBean.User">
<property name="name" value="user1"></property>
</bean>
</beans>
对XML文件进行引用,如下所示:
package com.hh.springbootTest.myConfig;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
@ImportResource("classpath:user.xml")
@Configuration
public class MyConfig {
}