一、給容器注入組件方法
1挽唉、@ComponentScan
包掃描滤祖,默認掃描當(dāng)前包下的所有包含@Component的組件,即:@Controller/@Service/@Repository/@Component
2瓶籽、@Bean
@Bean
和@Configuration
結(jié)合使用匠童,@Bean使用在方法上,用于導(dǎo)入第三方包的組件
3塑顺、@Import注入
-
@Import({xxx.class})
導(dǎo)入相關(guān)的類汤求,使用全包名作為名稱 -
@Import({ImportSelector.class})
實現(xiàn)ImportSelector的類中方法String[] selectImports(AnnotationMetadata var1)
,用于導(dǎo)入String[]包定義 -
@Import({ImportBeanDefinitionRegistrar.class})
實現(xiàn)ImportBeanDefinitionRegistrar的類中方法void registerBeanDefinitions(AnnotationMetadata var1, BeanDefinitionRegistry var2)
严拒,用于注冊導(dǎo)入信息
4扬绪、FactoryBean
- @Bean和實現(xiàn)FactoryBean接口的類整合使用
- 默認獲取到的是getObject創(chuàng)建的對象
- 要獲取工廠本身,加上前綴&
public interface FactoryBean<T> {
@Nullable
T getObject() throws Exception;
@Nullable
Class<?> getObjectType();
// 是否單例模式裤唠,true:單例模式挤牛,false:多例模式
default boolean isSingleton() {
return true;
}
}
class ColorFactoryBean Implement FactoryBean<Color>{
....
}
@Bean
public ColorFactoryBean colorFacotryBean(){
return new ColorFactoryBean();
}
二、bean的生命周期
bean的生命周期:創(chuàng)建-初始化-銷毀
1种蘸、 指定初始化和銷毀時調(diào)用方法
- 創(chuàng)建: 單實例 在容器每次啟動時創(chuàng)建對象墓赴;多實例 在每次獲取的時候創(chuàng)建對象
- 初始化:對象創(chuàng)建好,并賦值好的時候調(diào)用初始化方法
- 銷毀:單實例 容器關(guān)閉的時候航瞭;多實例:容器不管理這個Bean诫硕,容器不會調(diào)用銷毀方法
方法一:使用@Bean的屬性值
// initMethod : 初始化調(diào)用;destroyMethod:銷毀時調(diào)用
@Bean(initMethod = "",destroyMethod = "")
方法二:通過Bean實現(xiàn)InitializingBean和DisposableBean接口實現(xiàn)afterPropertiesSet()和destroy()方法
invokeInitMethods中執(zhí)行刊侯。
public class Car implements InitializingBean, DisposableBean {
public Car(){
}
@Override
public void afterPropertiesSet() throws Exception {
}
@Override
public void destroy() throws Exception {
}
}
方法三:使用@PostConstrust和@PreDestroy注解
本質(zhì)是在初始化前/后(beanProcessor)通過LifecycleMetadata注解信息注入章办,即在applyBeanPostProcessorsBeforeInitialization
和applyBeanPostProcessorsAfterInitialization
進行。
@Component
public class Car {
public Car(){
}
@PostConstruct
public void init(){
}
@PreDestroy
public void destroy() {
}
}
方法四:使用實現(xiàn)BeanPostProcessor 的類執(zhí)行器
// 對所有的bean實例實現(xiàn)以下執(zhí)行器
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
// 初始化方法之前
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
// 初始化方法之后
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
方法一二是初始化時執(zhí)行,方法三四是后置處理器在初始化前后執(zhí)行
三藕届、值注入
spring_@Value/@PropertySource..
@value:可以賦值給指定的屬性挪蹭,配合使用@Configuration可以獲得文件中的值,默認會獲得系統(tǒng)默認的application.properties翰舌,使用@Value("${id}")可以訪問properties文件的key-value嚣潜,也可以通過@PropertySource("classpath:applicaiton.yml")自定義設(shè)置冬骚,如果使用@Component導(dǎo)入椅贱,如果異常可采用@ConfigurationProperties(prefix="")注解定義前綴獲得只冻。
@PropertySource():在configuration類中指定使用的環(huán)境文件
@Autowired:注入容器庇麦,優(yōu)先按照類型注入,如果存在多個同類型喜德,按照屬性名稱相同注入
@Qualifier("xxx"):指定需要裝配的組件id山橄,而不是屬性名,使用在@Autowired上面舍悯,對@Autowired注入進行篩選航棱,選擇組件id符合Qulifier的組件注入
@Primary:與@Component組件一起,說明此組件優(yōu)先注入萌衬,優(yōu)先級小于@Quealifier
@Resource
不支持spring上述注解饮醇,基于java規(guī)范JSR-250
@Inject
需要導(dǎo)入Javax.inject
四、@profile
使用profile切換環(huán)境配置秕豫,將@profile("dev")添加到組件的注解上朴艰,表示該組件在dev環(huán)境時會創(chuàng)建使用,默認是default混移,即所有環(huán)境都會使用祠墅。
啟動1:命令行
// dev為自己在配置文件中定義的環(huán)境名稱
java -jar -Dspring.profiles.active=dev xxx.jar
啟動2:配置文件設(shè)置
// 在配置文件例如:application.properties
spring.profile.active=dev
// 或者如果是application.yml
spring:
profile:
active: dev
spring-boot的profile
在application.yml(application.properties)中設(shè)置active,即采用第二種啟動方式
spring:
profiles:
active: dev
在application.yml同級目錄創(chuàng)建application-dev.yml歌径,即在環(huán)境運行時毁嗦,自動導(dǎo)入的是application.yml和application-dev.yml配置。同時可以設(shè)置application-prod.yml生產(chǎn)環(huán)境回铛。在不同環(huán)境設(shè)置數(shù)據(jù)庫信息狗准,以備切換不同環(huán)境使用。
五勺届、spring aop
1驶俊、定義切面類
@Aspect
@Component
public class LogAspect {
@Pointcut("execution(* com.example.service.*.*(..))")
public void pointcut(){};
@Before("execution(public void com.example.service.RunService.start())")
public void logStart(JoinPoint joinPoint){
System.out.println("AOP切入————Before————"+joinPoint.getSignature().getName()+"————"+ Arrays.asList(joinPoint.getArgs()));
}
@After("pointcut()")
public void logAfter(JoinPoint joinPoint){
System.out.println("AOP切入————After————"+joinPoint.getSignature().getName()+"————"+ Arrays.asList(joinPoint.getArgs()));
}
@AfterReturning(value = "pointcut()",returning = "result")
public void logReturn(JoinPoint joinPoint, Object result){
System.out.println("AOP切入————Return————"+result+"————"+joinPoint.getSignature().getName()+"————"+ Arrays.asList(joinPoint.getArgs()));
}
@AfterThrowing(value = "pointcut()",throwing = "exception")
public void logException(JoinPoint joinPoint,Exception exception){
System.out.println("AOP切入————Exception————"+exception+"————"+joinPoint.getSignature().getName());
}
@Around("pointcut()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("AOP切入————Around1————");
Object proceed = joinPoint.proceed();
System.out.println("AOP切入————Around2————");
return proceed;
}
}
2、開啟代理
@EnableAspectJAutoProxy
@Configuration
public class MainConfig {
}
@Conditional