文章目录

  • 参考视频
  • 注解驱动的意义
  • 常用注解(重点)
    • 启动注解驱动
    • IoC
      • bean定义(@Component 、@Controller、@Service、 @Repository)
      • @Scope
      • bean生命周期(@PostConstruct、@PreDestroy)
      • @Bean (加载第三方资源)
    • DI
      • 非引用类型注入(@Value)
      • 引用类型注入(@Autowired、@Qualifier、@Primary、@Resource、@Inject、@Named)
      • 集合注入(待查找)
    • 加载第三方资源(@Bean)
      • Druid数据源
    • properties文件(@PropertySource)
    • 注解驱动(@Configurable,@ComponentScan)
    • 团队开发,第三方bean配置与管理(Import)
  • bean加载控制
    • bean的依赖关系(@DependsOn)
    • 配置类加载顺序(@Order)
    • bean的延迟加载(@Lazy)
    • 应用场景
  • 整合第三方技术(重点)
    • 整合mybatis
    • 整合Junit(注解)
  • IOC底层核心原理
    • IoC核心接口
    • 组件扫描过滤器(@ComponentScan)
      • ANNOTATION
      • CUSTOM
      • ASSIGNABLE_TYPE
      • ASPECTJ
      • REGEX
    • 自定义导入器
    • 自定义注册器
    • bean初始化过程

参考视频

https://www.bilibili.com/video/BV1yq4y1N78E?spm_id_from=333.337.search-card.all.click

注解驱动的意义

常用注解(重点)

启动注解驱动

在核心配置文件中添加如下配置

<!--启动注解驱动:指定扫描路径,也就是资源所在的包-->
<context:component-scan base-package="com.zs"/>

说明:递归扫描,读取java文件,spring注解,将有bean注解的资源加入IoC容器

IoC

bean定义(@Component 、@Controller、@Service、 @Repository)

类注解
设置该类为spring管理的bean

   <bean id="userService" class="com.zs.service.impl.UserServiceImpl"/>
@Service("userService")
public class UserServiceImpl  implements UserService {

说明:@Controller、@Service、@Repository是@Component的衍生注解,功能同@Component,分别表示表现层,业务层,数据层
value:定义bean的访问id

@Scope

类注解
设置创建对象的模式,singleton或不写就是单例模式,prototype是多例模式

   <bean id="userService" scope="prototype" class="com.zs.service.impl.UserServiceImpl"/>
@Service("userService")
@Scope("prototype")
public class UserServiceImpl  implements UserService {

bean生命周期(@PostConstruct、@PreDestroy)

   <bean id="userService" scope="prototype" init-method="init" destroy-method="destroy" class="com.zs.service.impl.UserServiceImpl"/>
@Service("userService")
@Scope("prototype")
public class UserServiceImpl  implements UserService {@PostConstructpublic void init(){System.out.println("init...");}@PreDestroypublic void destroy(){System.out.println("destroy...");}

@Bean (加载第三方资源)

@Bean
方法注解
设置该方法的返回值作为spring管理的bean

说明:第三方bean无法在其原码上修改,使用@Bean引入,替换配置文件中静态工厂实例工厂创建bean,不区分方法是否为静态或非静态

    <!--配置数据源--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean>
package com.zs.config;import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;@Component //此处后面会替换成专门的配置文件注解
public class JDBCConfig {@Bean("dataSource")public DruidDataSource getDataSource(){DruidDataSource ds = new DruidDataSource();ds.setDriverClassName("com.mysql.jdbc.Driver");ds.setUrl("jdbc:mysql://localhost:3306/testdb");ds.setUsername("iplat62");ds.setPassword("iplat62");return ds;}
}

DI

非引用类型注入(@Value)

@Value
属性注解、方法注解
设置对应属性的值或方法进行传参

    <!--要注入的资源--><bean id="userDao" class="com.zs.dao.impl.UserDaoImpl"><property name="username" value="${username}"/><property name="password" value="${password}"/></bean>
package com.zs.dao.impl;import com.zs.dao.UserDao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;@Repository("userDao")//别名不取默认为类名
public class UserDaoImpl implements UserDao {@Value("${username}")private String username;@Value("${password}")private String password;@Overridepublic void save() {System.out.println(username + "\t" + password);}
}

说明: value值支持读取properties文件中的属性值,通过类属性将properties中数据传入类中
value值支持SpEL
@value注解如果添加在属性上,可省略set方法(set方法的目的就是为属性赋值)

引用类型注入(@Autowired、@Qualifier、@Primary、@Resource、@Inject、@Named)

@Autowired、@Qualifier
属性,方法注解
设置对应属性的对象或对方法进行引用类型传参

相关属性:

  • required: 定义该属性是否允许为null @Autowired(required=false)

@Primary
类注解
设置类对应的bean按类型装配时优先装配

说明:设置多个类是会导致优先级无效,只能设置一个类优先

@Autowired //此时类型相同时会根据属性名自动识别
private UserDao userDao;@Repository("userDao")
public class UserDaoImpl implements UserDao{@Repository("userDao2")
public class UserDaoImpl2 implements UserDao{

匹配不到指定的bean,使用@Qualifier指定加载哪个bean

@Autowired //匹配不到
@Qualifier("userDao1")//指定引用哪个
private UserDao userDao;@Repository("userDao1")
public class UserDaoImpl implements UserDao{@Repository("userDao2")
public class UserDaoImpl2 implements UserDao{

bean不起名,默认使用类名

@Autowired //匹配不到,bean的名称没写默认是类名小写驼峰
private UserDao userDao;@Repository
public class UserDaoImpl implements UserDao{@Repository
public class UserDaoImpl2 implements UserDao{

指定优先加载的bean,只能用一个

@Autowired //匹配不到,bean的名称没写默认是类名小写驼峰
private UserDao userDao;@Repository
@Primary //优先加载该bean
public class UserDaoImpl implements UserDao{@Repository
public class UserDaoImpl2 implements UserDao{

@Inject、@Named、@Resource
说明:

  • @Inject、@Named是 JSR330中的注解,与@Autowired、@Qualifier完全相同
  • @Resource 是 JSR250 中的注解,可以简化书写格式

@Resource 相关属性

  • name: 设置注入的bean的id
  • type: 设置注入的bean的类型,接收的参数为Class类型

集合注入(待查找)

加载第三方资源(@Bean)

Druid数据源

    <!--配置数据源--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean>
package com.zs.config;import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;@Component //此处后面会替换成专门的配置文件注解
public class JDBCConfig {@Bean("dataSource")public DruidDataSource getDataSource(){DruidDataSource ds = new DruidDataSource();ds.setDriverClassName("com.mysql.jdbc.Driver");ds.setUrl("jdbc:mysql://localhost:3306/testdb");ds.setUsername("iplat62");ds.setPassword("iplat62");return ds;}
}

properties文件(@PropertySource)

@PropertySource
类注解
加载properties文件中的属性值

package com.zs.config;import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;@Component
@PropertySource(value = {"classpath:jdbc.properties","a.properties"},ignoreResourceNotFound = true)
public class JDBCConfig {@Value("${jdbc.driver}")private String driver;@Value("${jdbc.url}")private String url;@Value("${jdbc.username}")private String username;@Value("${jdbc.password}")private String password;@Bean("dataSource")public DruidDataSource getDataSource(){DruidDataSource ds = new DruidDataSource();ds.setDriverClassName(driver);ds.setUrl(url);ds.setUsername(username);ds.setPassword(password);
//        ds.setDriverClassName("com.mysql.jdbc.Driver");
//        ds.setUrl("jdbc:mysql://localhost:3306/testdb");
//        ds.setUsername("iplat62");
//        ds.setPassword("iplat62");return ds;}
}

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/testdb
jdbc.username=iplat62
jdbc.password=iplat62

说明:

  • 不支持*通配格式,一旦加载,所有spring控制的bean中均可使用对应属性值

相关属性

  • value:设置properties文件名
  • ignoreResourceNotFound: 如果资源未找到,是否忽略,默认false

注解驱动(@Configurable,@ComponentScan)

@Configuration、@ComponentScan
类注解
设置当前类为spring核心配置类

@Configurable//替换核心配置文件
@ComponentScan("com.zs") //注解扫描
public class SpringConfig{}

团队开发,第三方bean配置与管理(Import)

@Import
类注解
导入第三方bean作为spring控制的资源

@Configurable
@Import(JDBCConfig.class) //导入数据源配置类
public class SpringConfig{}

加载配置类

ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);

bean加载控制

bean的依赖关系(@DependsOn)

@DependsOn
类注解、方法注解
控制bean的加载顺序,使其在指定bean加载完毕后再加载

@Service("userService")
@DependsOn("userDao")//加载Service,需要先加载dao
public class UserServiceImpl implements UserService{

说明:

  • 配置在方法上,使@DependsOn指定的bean优先与@Bean配置的bean进行加载
  • 配置在类上,使@DependsOn指定的bean优先与当前类中所有@Bean配置的bean进行加载
  • 配置在类上,使@DependsOn指定的bean优先于@Component等配置的bean进行加载

配置类加载顺序(@Order)

配置类注解
控制配置类的加载顺序

@Order(1)
public class SpringConfig1{}@Order(2)
public class SpringConfig2{}ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig1.class,SpringConfig2.class);

bean的延迟加载(@Lazy)

类注解,方法注解
控制bean的加载时机,使其延迟加载

@Lazy
public class ClassName{}

应用场景

整合第三方技术(重点)

整合mybatis


JDBCConfig

package com.zs.config;import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;public class JDBCConfig {@Value("${jdbc.driver}")private String driver;@Value("${jdbc.url}")private String url;@Value("${jdbc.username}")private String username;@Value("${jdbc.password}")private String password;@Bean("dataSource")public DruidDataSource getDataSource(){DruidDataSource ds = new DruidDataSource();ds.setDriverClassName(driver);ds.setUrl(url);ds.setUsername(username);ds.setPassword(password);
//        ds.setDriverClassName("com.mysql.jdbc.Driver");
//        ds.setUrl("jdbc:mysql://localhost:3306/testdb");
//        ds.setUsername("iplat62");
//        ds.setPassword("iplat62");return ds;}
}

MybatisConfig

package com.zs.config;import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;public class MybatisConfig {@Beanpublic SqlSessionFactoryBean getSqlSessionFactoryBean(@Autowired DataSource dataSource){SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();ssfb.setTypeAliasesPackage("com.zs.domain");ssfb.setDataSource(dataSource);return ssfb;}@Beanpublic MapperScannerConfigurer getMapperScannerConfigurer(){MapperScannerConfigurer msc = new MapperScannerConfigurer();msc.setBasePackage("com.zs.mapper");return msc;}
}

SpringConfig

package com.zs.config;import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;@Configurable
@ComponentScan("com.zs")
@Import({JDBCConfig.class,MybatisConfig.class})
@PropertySource(value = {"classpath:jdbc.properties","a.properties"},ignoreResourceNotFound = true)
public class SpringConfig {}

AccountServiceImpl

package com.zs.service.impl;import com.zs.mapper.AccountDao;
import com.zs.domain.Account;
import com.zs.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service("accountService")
public class AccountServiceImpl implements AccountService {//注入dao@Autowiredprivate AccountDao accountDao;@Overridepublic void save(Account account) {accountDao.save(account);}@Overridepublic void delete(Integer id) {accountDao.delete(id);}@Overridepublic void update(Account account) {accountDao.update(account);}@Overridepublic List<Account> findAll() {return accountDao.findAll();}@Overridepublic Account findById(Integer id) {return accountDao.findById(id);}
}

AccountDao

package com.zs.mapper;import com.zs.domain.Account;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;import java.util.List;public interface AccountDao {@Insert("insert into account(name,money) values(#{name},#{money})")void save(Account account);@Delete("delete from account where id = #{id}")void delete(Integer id);@Update("update account set name=#{name},money=#{money} where id=#{id}")void update(Account account);@Select("select * from account")List<Account> findAll();@Select("select * from account where id=#{id}")Account findById(Integer id);
}

整合Junit(注解)


引入整合需要的坐标

        <dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.1.9.RELEASE</version></dependency>

UserServiceTest 创建测试类测试

package com.zs.service;import com.zs.config.SpringConfig;
import com.zs.domain.Account;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.util.List;//设定spring专用的类加载器
@RunWith(SpringJUnit4ClassRunner.class)
//加载核心配置文件
//@ContextConfiguration(value = {"classpath:applicationContext.xml"})
//设定加载的spring上下文对应的配置类
@ContextConfiguration(classes = SpringConfig.class)
public class UserServiceTest {@Autowiredprivate AccountService accountService;@Testpublic void testFindById(){Account ac = accountService.findById(1);}@Testpublic void testFindAll(){List<Account> all = accountService.findAll();all.forEach(System.out::println);}
}

IOC底层核心原理

IoC核心接口

  1. BeanFactory

    提供bean的基本操作

    • bean获取

      • 按名称获取
      • 按类型获取
    • bean供应商
    • bean基本信息
      • 是否存在
      • 是否单例
      • 类型获取
      • 类型检测
      • 别名获取
  2. HierarchicalBeanFactory

    提供bean分层结构,提出父子容器概念

    • 获取本地bean
  3. AutowireCapableBeanFactory

    提供bean自动装配功能

    • bean创建
    • bean装配
      • 装配方式
      • 前置动作
      • 后置动作
  4. ListableBeanFactory

提供容器内部遍历搜索bean的功能

  • 容器中的bean信息

    • bean存在性
    • bean的数量
    • bean的类型
  • bean相关信息获取
    • 由类型获取bean的名称
    • 由注解获取bean的名称
  • bean信息获取
    • bean的注解
    • bean的定义名称

组件扫描过滤器(@ComponentScan)


@ComponentScan
类注解
设置spring配置加载类扫描规则

        <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version></dependency>

ANNOTATION

@ComponentScan(value = "com.zs"                      //设置基础扫描路径excludeFilters = @ComponentScan.Filter( //设置过滤规则,过滤器type=FilterType.ANNOTATION          //按注解过滤classes=Repository.class)
)

CUSTOM

@Configurable
@ComponentScan(value = "com.zs",excludeFilters = @ComponentScan.Filter(type= FilterType.CUSTOM,classes = MyTypeFilter.class))
public class SpringConfig {}

自定义过滤器

package com.zs.config.filter;import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;import java.io.IOException;public class MyTypeFilter implements TypeFilter {@Overridepublic boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {//true拦截,false 不拦截ClassMetadata classMetadata = metadataReader.getClassMetadata();String className = classMetadata.getClassName();if (className.equals("")){return true;}return false;}
}

ASSIGNABLE_TYPE

ASPECTJ

REGEX

自定义导入器

CustomerImportSelector (工具类,直接用)
配合文件 import.properties使用

path=com.zs.dao.impl.*

将自定义导入器使用Import导入主配置类上

package com.zs.config.selector;import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AspectJTypeFilter;
import org.springframework.core.type.filter.TypeFilter;import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;public class CustomerImportSelector implements ImportSelector {private String expression;public CustomerImportSelector(){try {//初始化时指定加载的properties文件名Properties loadAllProperties = PropertiesLoaderUtils.loadAllProperties("import.properties");//设定加载的属性名expression = loadAllProperties.getProperty("path");}catch (IOException e){e.printStackTrace();}}@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {//1.定义扫描包的名称String[] basePackages = null;//2.判断有@Import注解的类上是否有@ComponentScan注解if (importingClassMetadata.hasAnnotation(ComponentScan.class.getName())) {//3.取出@ComponentScan注解的属性Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(ComponentScan.class.getName());//4.取出属性名称为basePackages属性的值basePackages = (String[]) annotationAttributes.get("basePackages");}//5.判断是否有此属性(如果没有ComponentScan注解则属性值为null,如果有ComponentScan注解,则basePackages默认为空数组)if (basePackages == null || basePackages.length == 0) {String basePackage = null;try {//6.取出包含@Import注解类的包名basePackage = Class.forName(importingClassMetadata.getClassName()).getPackage().getName();} catch (ClassNotFoundException e) {e.printStackTrace();}//7.存入数组中basePackages = new String[] {basePackage};}//8.创建类路径扫描器ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);//9.创建类型过滤器(此处使用切入点表达式类型过滤器)TypeFilter typeFilter = new AspectJTypeFilter(expression,this.getClass().getClassLoader());//10.给扫描器加入类型过滤器scanner.addIncludeFilter(typeFilter);//11.创建存放全限定类名的集合Set<String> classes = new HashSet<>();//12.填充集合数据for (String basePackage : basePackages) {scanner.findCandidateComponents(basePackage).forEach(beanDefinition -> classes.add(beanDefinition.getBeanClassName()));}//13.按照规则返回return classes.toArray(new String[classes.size()]);}
}

自定义注册器

使用方法同上,可以替换 扫描包的注解

package config.registrar;import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AspectJTypeFilter;
import org.springframework.core.type.filter.TypeFilter;import java.io.IOException;
import java.util.Map;
import java.util.Properties;public class CustomeImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {private String expression;public CustomeImportBeanDefinitionRegistrar(){try {//初始化时指定加载的properties文件名Properties loadAllProperties = PropertiesLoaderUtils.loadAllProperties("import.properties");//设定加载的属性名expression = loadAllProperties.getProperty("path");} catch (IOException e) {e.printStackTrace();}}@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {//1.定义扫描包的名称String[] basePackages = null;//2.判断有@Import注解的类上是否有@ComponentScan注解if (importingClassMetadata.hasAnnotation(ComponentScan.class.getName())) {//3.取出@ComponentScan注解的属性Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(ComponentScan.class.getName());//4.取出属性名称为basePackages属性的值basePackages = (String[]) annotationAttributes.get("basePackages");}//5.判断是否有此属性(如果没有ComponentScan注解则属性值为null,如果有ComponentScan注解,则basePackages默认为空数组)if (basePackages == null || basePackages.length == 0) {String basePackage = null;try {//6.取出包含@Import注解类的包名basePackage = Class.forName(importingClassMetadata.getClassName()).getPackage().getName();} catch (ClassNotFoundException e) {e.printStackTrace();}//7.存入数组中basePackages = new String[] {basePackage};}//8.创建类路径扫描器ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry, false);//9.创建类型过滤器(此处使用切入点表达式类型过滤器)TypeFilter typeFilter = new AspectJTypeFilter(expression,this.getClass().getClassLoader());//10.给扫描器加入类型过滤器scanner.addIncludeFilter(typeFilter);//11.扫描指定包scanner.scan(basePackages);}
}

bean初始化过程

BeanFactoryPostProcessor

  • 作用: 定义在bean工厂对象创建后,bean对象创建前执行的动作,用于对工厂进行创建后业务处理
  • 运行时机:当前操作用于对工厂进行处理,仅运行一次

BeanPostProcessor

  • 作用: 定义了所有bean初始化前后进行的统一动作,用于对bean进行创建前业务处理与创建后业务处理
  • 运行时机:当前操作伴随着每个bean的创建过程,每次创建bean均运行该操作

InitializingBean

  • 作用:定义了每个bean的初始化前进行的动作,属于非统一性动作,用于对bean进行创建前业务处理
  • 运行时机:当前操作伴随着任意一个bean的创建过程,保障其个性化业务处理

注意:需要被spring容器加载方可运行

FactoryBean

  • 对单一的bean的初始化过程进行封装,达到简化配置的目的

第二章 ---- spring注解开发相关推荐

  1. spring注解开发:容器中注册组件方式

    1.包扫描+组件标注注解 使用到的注解如下,主要针对自己写的类 @Controller @Service @Repository @Component @ComponentScan 参考 spring ...

  2. SpringBoot学习笔记-2:第二章 Spring Boot 配置

    第二章 Spring Boot 配置 1.YAML 配置 SpringBoot 全局配置文件 application.properties application.yml YAML 以数据为中心,比 ...

  3. 第二章 java常用开发工具以及程序的编写

    2019独角兽企业重金招聘Python工程师标准>>> 第二章 java常用开发工具以及程序的编写 1. 程序的概念         2. java程序的开发的三个步骤        ...

  4. 关于Spring注解开发教程,打包全送你

    摘要:spring是我们web开发中必不可少的一个框架,基于传统的xml方式配置bean总觉得太过繁琐,从spring2.5之后注解的出现可以大大简化我们的配置. 本文分享自华为云社区<如何高效 ...

  5. spring注解开发配置spring父子容器

    spring注解开发配置spring父子容器 官网 https://docs.spring.io/spring-framework/docs/current/spring-framework-refe ...

  6. Android群英传笔记——第二章:Android开发工具新接触

    Android群英传笔记--第二章:Android开发工具新接触 其实这一章并没什么可讲的,前面的安装Android studio的我们可以直接跳过,如果有兴趣的,可以去看看Google主推-Andr ...

  7. Spring注解开发学习笔记

    1 IOC 1.1 工厂模式 使用工厂中方法代替new形式创建对象的一种设计模式 1.2 Inversion of Control控制翻转 一种思想,用于消减代码间的耦合. 实现思想:利用工厂设计模式 ...

  8. 尚硅谷Spring注解开发学习笔记

    文章目录 前言 1.课程安排 1.1.容器 1.2.扩展原理 1.3.Web 2.配置文件开发 2.1.导入Spring-context依赖包 2.2.编写Spring配置文件 2.3.编写Perso ...

  9. Spring注解开发-Bean注册

    1.使用注解开发我们需要在applicationContext.xml文件中添加context标签. 在配置文件中开启注解扫描. <?xml version="1.0" en ...

最新文章

  1. 超级账本(Hyperledger Fabric)源码分析之一:总览
  2. 博途v15安装过程中提示出错_博途V15.1安装及无限重启和.net3.5SP1错误处理解决方法...
  3. 计算机网络OSI架构详细图
  4. bom .dom_MicroProfile 2.2 BOM导入支持
  5. 使用GZIP和压缩数据
  6. 操作系统学习笔记-06-系统调用
  7. 山石网科-Hillstone-SC-***(SSL-***)之配置终结篇
  8. VUE基础(躺着都能会)
  9. 机器视觉中图像颜色识别理论
  10. 无线路由器的信道选择
  11. 无惧失败,做一只逆流而上的鱼
  12. 使用google-jib部署springboot应用到阿里云Serverless kubernetes
  13. 用python画小仓鼠教程_看看萌萌哒的仓鼠是怎么画出来的,最详细的图文教程,别错过!...
  14. 【教程】C++-赋值语句
  15. 我的世界服务器修改宠物属性,我的世界怎么改宠物名字?
  16. modbus slave和modbus poll使用说明
  17. 合法标识符(C语言)
  18. javascript——从「最被误解的语言」到「最流行的语言」
  19. markdown图片左对齐问题
  20. matlab求解微分代数方程组,微分代数方程(DAE)的Matlab 解法.PDF

热门文章

  1. 速成pytorch学习——4天中阶API示范
  2. hadoop入门简介
  3. AJAX框架衣柜推拉门设计,带镜子的推拉门衣柜如何设计好看
  4. 表格序号_让Excel表格中的序号自动更新,再也不怕删除、插入行了
  5. 外贸电商ERP都有哪些值得用?
  6. 初学Go语言的学生管理系统
  7. python接口自动化(四十三)-公共模块 pymysql 连接mysql数据库(单独说明)
  8. git bash linux 命令,Git Bash的妙用 - 使用Linux命令
  9. 怎么调出全局搜索_局部静态变量只能初始化一次?它是怎么实现的
  10. 计算机算法知识点总结,2021计算机考研知识点总结(1)