zoukankan      html  css  js  c++  java
  • 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的方式:

    1. @Bean:Configuration类中,直接导入单个类
    2. @ComponentScan:包扫描,默认扫描@Controller、@Service、@Repository、@Component注解类
    3. @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,愿同您为友

    -- 星河有灿灿,愿与之辉

  • 相关阅读:
    03 python学习笔记-文件操作
    02 Python学习笔记-基本数据类型
    01 Python简介、环境搭建及包管理
    一、如何使用postman做接口测试笔记一
    django测试开发-1.开始Hello django!
    Oracle创建用户并给用户授权查询指定表或视图的权限
    ORA-00933 UNION 与 ORDER BY
    excel设置单元格不可编辑
    oracle之分组内的字符串连接
    10 款强大的JavaScript图表图形插件推荐
  • 原文地址:https://www.cnblogs.com/kiqi/p/14347460.html
Copyright © 2011-2022 走看看