您好,登錄后才能下訂單哦!
1.1 @Configuration
@Configuration
public class MainConfig {
}
@Configuration注解表明這個類是一個配置類,該類中應該包含如何在Spring應用上下文中創建bean的細節
1.2 @ComponentScan
@Configuration
@ComponentScan("per.ym")
public class MainConfig {
}
@ComponentScan注解用于啟用組件掃描,其作用同xml中配置<context:component-scan>。上述中的配置將會掃描per.ym包下的所有類,若不配置其value值,它會以配置類所在的包作為基礎包(base package)來掃描組件。如果你想同時掃描多個包,可以這樣配置:
@Configuration
@ComponentScan("per.ym, per.mm")
public class MainConfig {
}
在上面的例子中,所設置的基礎包是以String類型表示的。我認為這是可以的,但這種方法是類型不安全(not type-safe)的。如果你重構代碼的話,那么所指定的基礎包可能就會出現錯誤了。除了將包設置為簡單的String類型之外,@ComponentScan還提供了另外一種方法,那就是將其指定為包中所包含的類或接口:
@Configuration
@ComponentScan(basePackageClasses = {MyService.class, MyDao.class})
public class MainConfig {
}
你可以考慮在包中創建一個用來進行掃描的空標記接口(marker interface)。通過標記接口的方式,你依然能夠保
持對重構友好的接口引用,但是可以避免引用任何實際的應用程序代碼
1.3 @Controller, @Service, @ Repository, @Component
這幾個自然不用多說,算是見得最多的了,它們鎖修飾的類在被spring容器掃描到時會被加入到spring的管理之中。
@Controller對應表現層的Bean
@Service對應的是業務層Bean
@Repository對應數據訪問層Bean
@Component,當你不能明確的選擇上述3中,就用這個
Spring應用上下文中所有的bean都會給定一個ID,如果沒有明確指定,Spring會根據類名為其指定一個ID,也就是將類名的第一個字母變為小寫。你也可以這樣顯示的指定一個ID:
@Component("ymm")
public class Person() {
}
Spring支持將@Named(Java依賴注入規范中所提供的)作為@Component注解的替代方案。兩者之間有一些細微的差異,但是在大多數場景中,它們是可以互相替換的。
1.4 @Bean
@Bean注解會告訴Spring這個方法將會返回一個對象,該對象要注冊為Spring應用上下文中
的bean。方法體中包含了最終產生bean實例的邏輯。
@Configuration
public class MainConifg {
@Bean
public BookDao bookDao(){
return new BookDao();
}
}
@Bean注解會告訴Spring這個方法將會返回一個對象,該對象要注冊為Spring應用上下文中
的bean。方法體中包含了最終產生bean實例的邏輯。
默認情況下,bean的ID與帶有@Bean注解的方法名是一樣的。在上例中,bean的名字將會是bookDao。如果你想為其設置成一個不同的名字的話,那么可以重命名該方法,也可以通過name屬性指定一個不同的名字:
@Configuration
public class MainConifg {
@Bean(" ymBookDao")
public BookDao bookDao(){
return new BookDao();
}
}
還可以像這樣設置初始化方法和銷毀方法:
@Configuration
public class MainConifg {
@Bean(initMethod = "init", destroyMethod = "destroy")
public BookDao bookDao(){
return new BookDao();
}
}
這如同在xml中配置init-method="init" destroy-method="destory"一樣
1.5 @Autowired
借助@Autowired注解可以實現spring的自動裝配,自動裝配就是讓Spring自動滿足bean依賴的一種方法,在滿足依賴的過程中,會在Spring應用上下文中尋找匹配某個bean需求的其他bean
@Service
public class BookService {
@Autowired(required=false)
private BookDao bookDao;
}
你可以把@Autowired標注在屬性、構造器、setter方法上。實際上,Setter方法并沒有什么特殊之處,@Autowired注解甚至可以用在類的任何方法上。
除了自帶的@Autowired,spring還支持Java規范中的@Resource(JSR250)和@Inject(JSR330),它們之間的區別如下:
@Autowired:
a,默認優先按照類型去容器中找對應的組件:applicationContext.getBean(BookDao.class),如果有且只有一個 bean匹配依賴需求的話,那么這個bean將會被裝配進來;如果找到多個相同類型的組件,再將屬性的名稱作為組件的id去容器中查找applicationContext.getBean("bookDao");
b,@Qualifier("bookDao"):使用@Qualifier明確指定需要裝配的組件的id,而不是使用屬性名;
c,自動裝配默認一定要將屬性賦值好,沒有就會報錯;可以使用@Autowired(required=false);
d,@Primary:讓Spring進行自動裝配的時候,默認使用首選的bean;也可以使用@Qualifier指定需要裝配的bean的名字;
@Resource:
a,和@Autowired一樣實現自動裝配功能;默認是按照組件名稱進行裝配的;
b,不支持@Primary功能;
c,不支持required=false的功能;
@Inject:
a,和@Autowired一樣實現自動裝配功能;
b,不支持required=false的功能;
一個可能的例子:
@Configuration
@ComponentScan("per.ym.service")
public class MainConifgOfAutowired {
@Primary
@Bean("bookDao1")
public BookDao bookDao1(){
BookDao bookDao = new BookDao();
bookDao.setLable("1");
return bookDao;
}
@Bean("bookDao2")
public BookDao bookDao2(){
BookDao bookDao = new BookDao();
bookDao.setLable("2");
return bookDao;
}
}
@Service
public class BookService {
@Qualifier("bookDao1")
@Autowired(required=false)
private BookDao bookDao;
//@Resource(name="bookDao2")
//private BookDao bookDao;
//@Qualifier("bookDao2")
//@Inject
//private BookDao bookDao;
}
public class BookDao {
private String lable = "0";
public String getLable() {
return lable;
}
public void setLable(String lable) {
this.lable = lable;
}
}
1.6 @Import
通過導入的方式實現快速給容器中導入組件,其上可以配置3種類型的值,分別是普通bean,ImportSelector,ImportBeanDefinitionRegistrar。特別的,你可以導入一個被@Configuration注解修飾的bean,這和在一個spring配置文件中使用<import resource="classpath*:/spring/other.xml" />引入其他配置文件時相似的
@Configuration
@Import({MainConfig2.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MainConfig {
}
MainConfig2可以是另一個配置類或者普通的bean:
@Configuration
public class MainConfig2 {
@Bean
public Person person(){
return new Person();
}
}
ImportSelector,其selectImports方法返回的數組中應包含要導入容器的bean的全類名
public class MyImportSelector implements ImportSelector {
//返回值,就是到導入到容器中的組件全類名
//AnnotationMetadata:當前標注@Import注解的類的所有注解信息
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//方法不要返回null值,否則會有NPE
return new String[]{"per.ym.bean.Car","per.ym.bean.Dog"};
}
}
ImportBeanDefinitionRegistrar,調用BeanDefinitionRegistry.registerBeanDefinition手工注冊想要添加到容器中的bean
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* AnnotationMetadata:當前類的注解信息
* BeanDefinitionRegistry:BeanDefinition注冊類;
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//指定Bean定義信息
RootBeanDefinition beanDefinition = new RootBeanDefinition(Red.class);
//注冊一個Bean,指定bean名
registry.registerBeanDefinition("red", beanDefinition);
}
}
1.7 @Conditional
放在類上,當滿足條件時,這個類中配置的所有bean注冊才能生效
放在方法上,當滿足條件時,才向容器中注冊當前bean
@Conditional({WindowsCondition.class})
@Configuration
public class MainConfig {
@Conditional(LinuxCondition.class)
@Bean("linus")
public Person person(){
return new Person("linus");
}
}
/**
* ConditionContext:判斷條件能使用的上下文(環境)
* AnnotatedTypeMetadata:注釋信息
*/
//判斷是否windows系統
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//1、能獲取到ioc使用的beanfactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
//2、獲取類加載器
ClassLoader classLoader = context.getClassLoader();
//3、獲取到bean定義的注冊類
BeanDefinitionRegistry registry = context.getRegistry();
//4、獲取當前環境信息
Environment environment = context.getEnvironment();
String property = environment.getProperty("os.name");
if(property.contains("Windows")){
return true;
}
return false;
}
}
1.8 @Profile
根據當前環境,動態的激活和切換一系列組件的功能;指定組件在哪個環境的情況下才能被注冊到容器中,不指定,任何環境下都能注冊這個組件
加了環境標識的bean,只有這個環境被激活的時候才能注冊到容器中
寫在配置類上,只有是指定的環境的時候,整個配置類里面的所有配置才能開始生效
@PropertySource("classpath:/dbconfig.properties")
@Configuration
public class MainConfigOfProfile implements EmbeddedValueResolverAware{
@Value("${db.user}")
private String user;
private StringValueResolver valueResolver;
private String driverClass;
@Profile("test")
@Bean("testDataSource")
public DataSource dataSourceTest(@Value("${db.password}")String pwd) throws Exception{
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(pwd);
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
dataSource.setDriverClass(driverClass);
return dataSource;
}
@Profile("dev")
@Bean("devDataSource")
public DataSource dataSourceDev(@Value("${db.password}")String pwd) throws Exception{
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(pwd);
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/dev");
dataSource.setDriverClass(driverClass);
return dataSource;
}
@Profile("prod")
@Bean("prodDataSource")
public DataSource dataSourceProd(@Value("${db.password}")String pwd) throws Exception{
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(pwd);
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/prod");
dataSource.setDriverClass(driverClass);
return dataSource;
}
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
this.valueResolver = resolver;
driverClass = valueResolver.resolveStringValue("${db.driverClass}");
}
}
db.properties:
db.user=root
db.password=123456
db.driverClass=com.mysql.jdbc.Driver
啟動命令行中設置環境參數:
-Dspring.profiles.active=test
代碼方式設置:
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfProfile.class);
applicationContext.getEnvironment().setActiveProfiles("dev");
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。