Spring基础知识点 - 注解详解
XML文件配置
// 使用xml配置文件完成Spring容器的创建
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = (Person) context.getBean("person");
}
}
<!-- applicationContext.xml配置文件 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="person" class="top.kiqi.spring.demo.xml.project.Person">
<property name="name" value="kiqi"></property>
<property name="age" value="26"></property>
</bean>
</beans>
Annotation注解
beanDefinition
@Configuration
@Configuration: 用于定义配置类,替代application.xml配置文件(等价于<Beans></Beans>
)
// spring configuration类作为配置类(@Configuration) --- AnnotationConfigApplicationContext
// @Bean注解,默认以方法名作为bean name.
public class Test {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class);
Person person = (Person) context.getBean("person");
System.out.println(person);
}
}
@Configuration
public class MyConfiguration {
@Bean
public Person person(){
return new Person("kiqi",17);
}
}
@ComponentScan
@ComponentScan:配置扫描路径(等价于<context:component-scan base-package="*"/>
)
@Configuration
@ComponentScan(value = "top.kiqi.spring.demo.annotation.project", useDefaultFilters = true)
// includeFilters = {@Filter(type = FilterType.ANNOTATION,value = {Controller.class})},useDefaultFilters = false)
// includeFilters = {@Filter(type = FilterType.ASSIGNABLE_TYPE,value = {UserBO.class})},useDefaultFilters = false)
// includeFilters = {@Filter(type = FilterType.CUSTOM,value = {MyTypeFilter.class})},useDefaultFilters = false))
public class MyConfiguration {}
// @ComponentScan注解,配置扫描路径以及过滤方式(Filter:默认扫描含有@Component,@Service,@Controller和@Repository注解的类)
// @Filter(type = FilterType.ANNOTATION,value = {Controller.class} --- 注解式过滤器,注册所有带@Controller注解的类
// @Filter(type = FilterType.ASSIGNABLE_TYPE,value = {UserBO.class} --- 类型式过滤器,注册类型为UserBO.class的类
// @Filter(type = FilterType.CUSTOM,value = {MyTypeFilter.class} --- 采用用户创建的过滤器进行过滤
// 类型拦截器,用于@ComponentScan注解中设置类的过滤方式
public class MyTypeFilter implements TypeFilter{
/**
* @param metadataReader 获取当前正在操作的信息
* @param metadataReaderFactory 获取上下文中所有的信息
* @return
* @throws IOException
*/
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
//获取当前扫描到的类的注解信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取当前扫描到的类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
//获取当前扫描到的类的资源
Resource resource = metadataReader.getResource();
String className = classMetadata.getClassName();
if(className.contains("BO")){
System.out.println("register bean : " + className);
return true;
}
return false;
}
}
@Scope
@Scope:设置Bean对象的作用域
// @scope注解,默认 单例
// prototype 多例
// singleton 单例
// request 主要应用于web模块,同一次请求只创建一个实例
// session 主要应用于web模块,同一个session只创建一个实例
@Configuration
public class MyConfiguration {
@Bean
@Scope("prototype")
public Person person(){
return new Person("kiqi",17);
}
}
@Lazy
@Lazy:设置Bean对象是否懒加载
// @Lazy注解 - 默认值为true
// 若未设置Lazy注解,对于单例对象,默认提前加载
// 若未设置Lazy注解,对于原型对象,默认懒加载
@Configuration
public class MyConfiguration {
@Bean
@Lazy()
public Person person(){
return new Person("kiqi",17);
}
}
@Conditional
@Conditional:条件加载,只有符合条件时,才会加载Bean到容器中
// @Condition注解,条件加载,只有符合条件时,才会加载Bean到容器中
// @PropertySource("application.properties") 读取解析配置文件并加入到容器的Environment中
public class Test {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfiguration.class);
UserBO userBO = context.getBean("userBO", UserBO.class);
System.out.println(userBO);
}
}
// 条件对象,实现Condition
public class ConditionLinux implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
Environment environment = conditionContext.getEnvironment();
String name = environment.getProperty("io.name", "Linux");
return name.contains("inux");
}
}
@Configuration
@PropertySource("application.properties")
public class MyConfiguration {
@Conditional(ConditionWindows.class)
@Bean("userBO")
public UserBO windows(){
System.out.println("条件注入 - windows");
return new UserBO("windows",17);
}
@Conditional(ConditionLinux.class)
@Bean("userBO")
public UserBO linux(){
System.out.println("条件注入 - linux");
return new UserBO("linux",16);
}
}
@Import
@Import:向IOC容器中导入Bean
// Configuration类
// Import导入 ①普通Bean,②ImportSelector实现类,③ImportBeanDefinitionRegistrar实现类。
@Configuration
@Import(value = {ImportClass.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MyConfiguration {
@Bean
// FactoryBean,实际会将:importFactoryBeanBean实例注册到IOC容器中
public MyFactoryBean importFactoryBeanBean(){
return new MyFactoryBean();
}
}
// FactoryBean类
// 获取Bean对象时,会调用getObject()方法将真实对象注册到IOC容器(如果是解引用&获取,则返回FactoryBean对象)
public class MyFactoryBean implements FactoryBean<ImportFactoryBeanBean> {
@Override
public ImportFactoryBeanBean getObject() throws Exception {
return new ImportFactoryBeanBean();
}
@Override
public Class<?> getObjectType() {
return ImportFactoryBeanBean.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
// ImportSelector类
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{
"top.kiqi.spring.demo.annotation.core.configure.a4_import.entity.ImportSelectorBean"
};
}
}
// ImportBeanDefinitionRegistrar类
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* @param annotationMetadata 当前类的注解信息
* @param registry 完成BeanDefinition的注册
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
boolean person = registry.containsBeanDefinition("top.kiqi.spring.demo.annotation.core.configure.a4_import.entity.ImportClass");
if(person){
BeanDefinition beanDefinition = new RootBeanDefinition(ImportRegistrarBean.class);
registry.registerBeanDefinition("importRegistrarBean",beanDefinition);
}
}
}
向IOC容器中注册Bean的方式:
- @Bean:Configuration类中,直接导入单个类
- @ComponentScan:包扫描,默认扫描@Controller、@Service、@Repository、@Component注解类
- @Import:快速给容器导入组件Bean
- BeanName 直接导入单个Bean(beanName为全类名)
- ImportSelector 自定义导入规则
- ImportBeanDefinitionRegistrar 使用BeanDefinitionRegistry手动导入Bean到IoC容器中
FactoryBean接口:为需要注入的对象创建FactoryBean
,由FactoryBean.getObject()将Bean注入到容器的Bean
population
- Component
- @Component:泛指组件
- @Controller:控制层组件
- @Service:业务层组件
- @Repository(DAO):数据访问层组件
- DI
- @Value:普通数据类型赋值 ①直接赋值 ②\({},El表达式赋值 ③\){},从配置文件中获取
- @Autowired:默认按类型(byType)装配,当和Qualifier("name")一同使用时,为按名称(byName)装配
- @Qualifier 如上
- @Resource: 默认按名称(byName)装配,如果找不到与名称匹配的bean时,会按类型(byType)装配
- @PropertySource:加载配置文件,并将属性保存到ApplicationContext的Environment中
- @Primary:自动装配时,当出现多个Bean候选时,将选用带有Primary标签的bean
aspects
- @EnableAspectJAutoProxy:开启AOP切面代理
- @Aspect:声明类为切面类
- @Pointcut(EL表达式):声明切面(通过EL表达式筛选出所有需要切入的方法 - 即:切点)
- Advice
- @Before: 前置通知
- @Around:环绕通知(前置先于普通前置通知执行,后置先于普通后置通知执行)
- @After: 后置通知(普通后置通知先于条件后置通知执行)
- @AfterReturning:正常返回情况下后置通知
- @AfterThrowing:抛出异常情况下后置通知
@Aspect
@Component
public class LogAspect {
// EL表达式,代理所有带有LogAnnotation注解的类和方法。
@Pointcut("@annotation(top.kiqi.spring.demo.annotation.core.aspects.annotation.LogAnnotation)")
public void pointCut(){}
@Before("pointCut()")
public void doBefore(JoinPoint joinPoint){
System.out.println("Before Advice...");
System.out.println("-- 目标方法名为:" + joinPoint.getSignature().getName());
System.out.println("-- 目标方法所属类的简单类名:" + joinPoint.getSignature().getDeclaringType().getSimpleName());
System.out.println("-- 目标方法所属类的类名:" + joinPoint.getSignature().getDeclaringTypeName());
System.out.println("-- 目标方法声明类型:" + joinPoint.getSignature().getModifiers());
//获取传入目标方法的参数
Object[] args = joinPoint.getArgs();
System.out.println("-- 被代理的对象:" + joinPoint.getTarget());
System.out.println("-- 代理对象自己:" + joinPoint.getThis());
}
@Around("pointCut()")
public void around(ProceedingJoinPoint pjp){
System.out.println("Aronud before...");
try {
pjp.proceed();
} catch (Throwable e) {
System.out.println("Aronud throw...");
e.printStackTrace();
}
System.out.println("Aronud after...");
}
@After("pointCut()")
public void doAfter(JoinPoint joinPoint){
System.out.println("After Advice...");
}
@AfterReturning(pointcut="pointCut()",returning="returnVal")
public void afterReturn(JoinPoint joinPoint,Object returnVal){
System.out.println("After Returning Advice:" + returnVal);
}
@AfterThrowing(pointcut="pointCut()",throwing="error")
public void afterThrowing(JoinPoint joinPoint,Throwable error){
System.out.println("After Throwing Advice..." + error);
}
}
// 自定义注解类
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface LogAnnotation {
String value() default "default";
}
事务注解
- @EnableTransactionManagement:开启Spring事务代理
- @Transactional:声明事务
- propagation:事务传播特性(REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER、NESTED)
- isolation:事务隔离级别(DEFAULT、READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ、SERIALIZABLE)
- readOnly:方法中没有需要处理的事务,比如读取数据,可以设置 read-only 为 true
- timeout:事务超时时间
- rollbackFor:设置当抛出何种异常时执行回滚操作(默认在遇到RuntimeException的时候会回滚)
Aware类接口
如果一个Bean想要依赖注入一些特殊的与Spring容器有关的属性,需要Bean类实现Aware接口。
- BeanNameAware:beanName
- BeanClassLoaderAware:beanClassLoader
- BeanFactoryAware:beanFactory
- EnvironmentAware:environment
- ApplicationContextAware:applicationContext
欢迎疑问、期待评论、感谢指点 -- kiqi,愿同您为友
-- 星河有灿灿,愿与之辉