Spring 基本注解

1.配置类注解

@Configuration: 配置类注解,等同于配置文件,告诉Spring这是一个配置类

@Configuration 
public class MainConfig {
	
}

2.包扫描注解

@ComponentScan:包扫描注解

  • value:指定要扫描的包
  • excludeFilters = Filter[] :指定扫描的时候按照什么规则排除那些组件
  • includeFilters = Filter[] :指定扫描的时候只需要包含哪些组件

@Filter:包扫描过滤注解

  • classes : 过滤的类、注解或者自定义过滤器
  • FilterType.ANNOTATION:按照注解
  • FilterType.ASSIGNABLE_TYPE:按照给定的类型;
  • FilterType.ASPECTJ:使用ASPECTJ表达式
  • FilterType.REGEX:使用正则指定
  • FilterType.CUSTOM:使用自定义规则
@ComponentScans(
    value = {
      @ComponentScan(
          value = "com.xiao7",
          includeFilters = {
            @Filter(
                type = FilterType.ANNOTATION,
                classes = {Controller.class}),
            @Filter(
                type = FilterType.ASSIGNABLE_TYPE,
                classes = {BookService.class}),
            @Filter(
                type = FilterType.CUSTOM,
                classes = {MyTypeFilter.class})
          },
          useDefaultFilters = false)
    })

扫描规则过滤:

public class MyTypeFilter implements TypeFilter {

	/**
	 * metadataReader:读取到的当前正在扫描的类的信息
	 * metadataReaderFactory:可以获取到其他任何类信息的
	 */
	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();
		System.out.println("--->"+className);
		if(className.contains("er")){
			return true; //返回true表示过滤掉,不扫描注册
		}
		return false;
	}

}

3.容器中注册组件注解

@Bean:给容器中注册一个Beanid默认是用方法名作为id

  • value:指定Beanid
  • initMethod: 指定初始化方法
  • destroyMethod: 指定销毁方法

@Scope:调整作用域:

  • prototype:多实例的,每次获取的时候才会调用方法创建对象

  • singleton:单实例的(默认值),每次获取就是直接从容器中拿

  • request:同一次请求创建一个实例 session:同一个session创建一个实例

@Lazy:懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;

    @Scope("prototype")
    @Lazy
	@Bean("person")
	public Person person01(){
		return new Person("lisi", 20);
	}

@Controller:控制层注解
@Service:业务层注解
@Repositor:仓储层注解
@Component:组件注解

@Import:快速给容器中导入一个组件,可以选择导入

  • Class:直接导入类
  • ImportSelector:自定义逻辑返回需要导入的组件,返回需要导入的组件的全类名数组
  • ImportBeanDefinitionRegistrar:手动注册bean到容器中

使用注解:

@Import({Color.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MainConfig2 {
}

自定义导入:

//自定义逻辑返回需要导入的组件
public class MyImportSelector implements ImportSelector {
	//返回值,就是到导入到容器中的组件全类名
	//AnnotationMetadata:当前标注@Import注解的类的所有注解信息
	public String[] selectImports(AnnotationMetadata importingClassMetadata) {
		// TODO Auto-generated method stub
		//importingClassMetadata
		//方法不要返回null值
		importingClassMetadata.getAnnotationTypes();
		return new String[]{"com.atguigu.bean.Blue","com.atguigu.bean.Yellow"};
	}

}

手动导入:

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
	/**
	 * AnnotationMetadata:当前类的注解信息
	 * BeanDefinitionRegistry:BeanDefinition注册类;
	 * 把所有需要添加到容器中的bean;调用
	 * BeanDefinitionRegistry.registerBeanDefinition手工注册进来
	 */
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		boolean definition = registry.containsBeanDefinition("com.atguigu.bean.Red");
		boolean definition2 = registry.containsBeanDefinition("com.atguigu.bean.Blue");
		if(definition && definition2){
			//指定Bean定义信息;(Bean的类型,Bean。。。)
			RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);
			//注册一个Bean,指定bean名
			registry.registerBeanDefinition("rainBow", beanDefinition);
		}
	}

}

@Conditional:按照一定的条件进行判断,满足条件给容器中注册bean

  @Conditional(LinuxCondition.class)
  @Bean("linus")
  public Person person() {
    return new Person("linus", 48);
  }

条件类:


//判断是否linux系统
public class LinuxCondition implements Condition {

	/**
	 * ConditionContext:判断条件能使用的上下文(环境)
	 * AnnotatedTypeMetadata:注释信息
	 */
	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
		// TODO是否linux系统
		//1、能获取到ioc使用的beanfactory
		ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
		//2、获取类加载器
		ClassLoader classLoader = context.getClassLoader();
		//3、获取当前环境信息
		Environment environment = context.getEnvironment();
		//4、获取到bean定义的注册类
		BeanDefinitionRegistry registry = context.getRegistry();
		
		String property = environment.getProperty("os.name");

		//可以判断容器中的bean注册情况,也可以给容器中注册bean
		boolean definition = registry.containsBeanDefinition("person");
		if(property.contains("linux")){
			return true;
		}
		
		return false;
	}

}

4.属性加载类注解

@PropertySource:读取外部配置文件中的k/v保存到运行的环境变量中
@Value:加载完外部的配置文件以后使用${}取出配置文件的值

@PropertySource(value={"classpath:/person.properties"})
@Configuration
public class MainConfigOfPropertyValues {

	@Value("${db.user}")
	private String user;
	
	@Bean
	public Person person(){
		return new Person();
	}

}

@Profile:满足该激活环境时配置

  • 使用命令行动态参数: 在虚拟机参数位置加载 -Dspring.profiles.active=dev
  • 代码的方式激活某种环境
  • springBoot配置文件中spring.profiles.active=dev
	@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/ssm_crud");
		dataSource.setDriverClass(driverClass);
		return dataSource;
	}

5.监听器和后置处理器

ApplicationListener监听器

ApplicationListener:实现接口注册时间监听器

@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
	//当容器中发布此事件以后,方法触发
	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		// TODO Auto-generated method stub
		System.out.println("收到事件:"+event);
	}
}

@EventListener:监听某个时间的发布

@Service
public class UserService {
	@EventListener(classes={ApplicationEvent.class})
	public void listen(ApplicationEvent event){
	System.out.println("UserService。。监听到的事件:"+event);
	}
}

发布事件:

@Test
public void test01(){
		AnnotationConfigApplicationContext applicationContext  = new AnnotationConfigApplicationContext(ExtConfig.class);
		//发布事件;
		applicationContext.publishEvent(new ApplicationEvent(new String("我发布的时间")) {
		});
		applicationContext.close();
}

ApplicationListener:监听器可以监听spring容器的不同时间的事件
spring容器的可实现监听器:
在这里插入图片描述
springBoot容器的可实现监听器:
在这里插入图片描述

PostProcessor 后置处理器

  • BeanPostProcessor: 在Bean的初始化前后进行处理工作
  • BeanFactoryPostProcessor:Bean工厂的后置处理器
  • BeanDefinitionRegistryPostProcessor:Bean的定义注册后置处理器

BeanPostProcessor

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);
		return bean;
	}

}

BeanFactoryPostProcessor

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

		System.out.println("MyBeanFactoryPostProcessor...postProcessBeanFactory...");
		int count = beanFactory.getBeanDefinitionCount();
		String[] names = beanFactory.getBeanDefinitionNames();
		System.out.println("当前BeanFactory中有"+count+" 个Bean");
		System.out.println(Arrays.asList(names));
	}

}

BeanDefinitionRegistryPostProcessor

@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor{

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("MyBeanDefinitionRegistryPostProcessor...bean的数量:"+beanFactory.getBeanDefinitionCount());
	}

	//BeanDefinitionRegistry Bean定义信息的保存中心,以后BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个bean定义信息创建bean实例;
	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("postProcessBeanDefinitionRegistry...bean的数量:"+registry.getBeanDefinitionCount());
		//RootBeanDefinition beanDefinition = new RootBeanDefinition(Blue.class);
		AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Blue.class).getBeanDefinition();
		registry.registerBeanDefinition("hello", beanDefinition);
	}

}

6.事务支持注解

@EnableTransactionManagement:开启spring的事务支持

  • 实际是使用Import注册了TransactionManagementConfiguration
  • 默认是Proxy,可设置adviceMode注册AspectJ事务管理配置类
@EnableTransactionManagement
@ComponentScan("com.atguigu.tx")
@Configuration
public class TxConfig {
	
	//数据源
	@Bean
	public DataSource dataSource() throws Exception{
		ComboPooledDataSource dataSource = new ComboPooledDataSource();
		dataSource.setUser("root");
		dataSource.setPassword("123456");
		dataSource.setDriverClass("com.mysql.jdbc.Driver");
		dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
		return dataSource;
	}
	@Bean
	public JdbcTemplate jdbcTemplate() throws Exception{
		return new JdbcTemplate(dataSource());
	}
	//注册事务管理器在容器中
	@Bean
	public PlatformTransactionManager transactionManager() throws Exception{
		return new DataSourceTransactionManager(dataSource());
	}
}

@Transactional:事务注解

  • propagation:指定事务的传播行为, 默认:Propagation.REQUIRED
  • isolation:指定事务的隔离级别,默认:Isolation.DEFAULT,使用数据库的隔离级别
  • rollbackForClassName:指定事务回滚的捕捉异常,默认:RuntimeExpection运行时异常

使用事务:

@Service
public class UserService {
	@Autowired
	private UserDao userDao;
	@Transactional
	public void insertUser(){
		userDao.insert();
		System.out.println("插入完成...");
//		int i = 10/0;
	}

}

7.Aop切面注解

@EnableAspectJAutoProxy:开启Aop切面支持
@Aspect: 告诉Spring当前类是一个切面类

@Pointcut:切点匹配

  • execution():用于匹配方法执行的连接点
    例子:
    execution(public * *(..)) 定义任意公共方法的执行
    execution(* set*(..)) 定义任何一个以"set"开始的方法的执行
    execution(* com.xyz.service.AccountService.*(..)) 定义AccountService 接口的任意方法的执行
    execution(* com.xyz.service.*.*(..)) 定义在service包里的任意方法的执行
    execution(* com.xyz.service ..*.*(..)) 定义在service包和所有子包里的任意类的任意方法的执行
    execution(* com.test.spring.aop.pointcutexp…JoinPointObjP2.*(…)) 定义在pointcutexp包和所有子包里的JoinPointObjP2类的任意方法的执行:

  • args(): 用于匹配当前执行的方法传入的参数为指定类型的执行方法
    例子:
    args(String) 参数为String类型(运行时决定)的方法.

  • this(): 匹配一个类或者接口的实现类
    例子:
    this(com.test.spring.aop.pointcutexp.Intf) 实现了Intf接口的所有类,如果Intf不是接口,限定Intf单个类.

  • target(): 针对类的匹配条件
    例子:
    @target(org.springframework.transaction.annotation.Transactional) 带有@Transactional标注的所有类的任意方法.

  • within(): 用于匹配指定类

  • @within():用于匹配所以持有指定注解类的方法
    例子:
    within(com.test.spring.aop.pointcutexp.*) pointcutexp包里的任意类.
    @within(org.springframework.transaction.annotation.Transactional) 带有@Transactional标注的所有类的任意方法.

  • @args():于匹配当前执行的方法传入的参数持有指定注解的执行
    例子:
    @args(org.springframework.transaction.annotation.Transactional) 参数带有@Transactional标注的方法.

  • @target():用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解
    例子:
    @target(org.springframework.transaction.annotation.Transactional) 带有@Transactional标注的所有类的任意方法.

  • @annotation:用于匹配当前执行方法持有指定注解的方法
    例子:
    @annotation(org.springframework.transaction.annotation.Transactional) 带有@Transactional标注的任意方法.

@Aspect
public class LogAspects {
	
	//抽取公共的切入点表达式
	//1、本类引用
	//2、其他的切面引用
	@Pointcut("execution(public int com.atguigu.aop.MathCalculator.*(..))")
	public void pointCut(){};
	
	//@Before在目标方法之前切入;切入点表达式(指定在哪个方法切入)
	@Before("pointCut()")
	public void logStart(JoinPoint joinPoint){
		Object[] args = joinPoint.getArgs();
		System.out.println(""+joinPoint.getSignature().getName()+"运行。。。@Before:参数列表是:{"+Arrays.asList(args)+"}");
	}
	
	@After("com.atguigu.aop.LogAspects.pointCut()")
	public void logEnd(JoinPoint joinPoint){
		System.out.println(""+joinPoint.getSignature().getName()+"结束。。。@After");
	}
	
	//JoinPoint一定要出现在参数表的第一位
	@AfterReturning(value="pointCut()",returning="result")
	public void logReturn(JoinPoint joinPoint,Object result){
		System.out.println(""+joinPoint.getSignature().getName()+"正常返回。。。@AfterReturning:运行结果:{"+result+"}");
	}
	
	@AfterThrowing(value="pointCut()",throwing="exception")
	public void logException(JoinPoint joinPoint,Exception exception){
		System.out.println(""+joinPoint.getSignature().getName()+"异常。。。异常信息:{"+exception+"}");
	}

}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值