Spring系列--注解
第一章 注解基础概念
1、什么是注解编程
指的是在类或者方法上加入特定的注解(@xxxx),完成特定功能的开发
@Component
public class XXX{}
2、为什么要讲注解编程
1. 注解开发方便
代码简洁 开发速度大大提高
2. Spring 开发潮流
Spring2.x引入注解 Spring3.x完善注解 SpringBoot普及 推广注解编程
3、注解的作用
-
替换xml这种配置形式,简化配置
-
替换接口,实现调用双方的契约性
通过注解的方式,在功能调用者和功能提供者之间达成约定,进而进行功能的调用,因为注解应用更为灵活方便,所以在现在开发中,更推荐通过注解的形式完成
4、Spring注解的发展历程
1. Spring2.x 开始支持注解编程 @Component @Service @Scope....
目的:提供这些注解只是为了在某些情况下简化xml的配置,作为xml开发的有益补充
2. Spring3.x @Configuration @Bean...
目的:彻底替换xml,基于纯注解编程
3. Spring4.x SpringBoot
提倡使用注解常见开发
5、Spring注解开发的一个问题
Spring基于注解进行配置后,还能否解耦合呢
-- 在Spring框架应用注解时,如果对注解配置的内容不满意,可以通过Spring配置文件进行覆盖的
第二章 Spring的基础注解(Spring2.x)
1、对象创建相关注解
-
搭建开发环境
<context:component-scan base-package="com.bai"/> 作用:让Spring框架在设置包及其子包中扫描对应的注解,使其生效 -
对象创建相关注解
-
@Component
作用:替换原有spring配置文件中的<bean>标签 注解:id属性 component注解,提供了默认的设置方式,受单词首字母小写 class属性通过反射获得class内容 -
@Component细节
-
如何显示指定工厂创建对象的id值
@Conponent("") -
Spring配置文件覆盖注解配置内容
applicationContext.xml <bean id="u" class="com.bai.bean.User"/> id值和class值 要和注解中的设置保持一致
-
-
@Component的衍生注解
@Repository @Service @Controller 注意:本质上这些衍生注解就是@Component 目的:准确的表达一个类型的作用 注意:Spring整合Mybatis开发过程中,不适用@Repostitory @Conponent -
@Scope注解
作用:控制简单对象创建次数 注意:不添加@Scope Spring提供默认值 singleten -
@Lazy注解
作用:延迟创建单实例对象 注意:一旦使用了@Lazy注解后,Spring会在使用这个对象时候,进行这个对象的创建
-
-
生命周期方法相关注解
1. 初始化相关方法@PostConstruct InitializingBean <bean init-method=""/> 2. 销毁方法@PreDestroy DisposableBean <bean destory-method=""/> 注意:1.上述的两个注解并不是Spring提供的,JSP(javaEE规范)520 2.再一次验证,通过注解实现了接口的契约性
2、注入相关注解
-
用户自定义类型@Autowired
@Autowired细节 1. Autowired注解基于类型进行注入【推荐】 基于类型的注入:注入对象的类型,必须与目标成员变量类型相同或者是其子类(实现类) 2. Autowired Qualifier 基于名字进行注入【了解】 基于名字注入:注入对象的id值,必须与Qualifier注解中设置的名字相同 3. Autowired注解放置位置 a) 放置在对应成员变量的set方法上 b) 直接把这个注解放置在成员变量之上,Spring通过反射直接对成员变量进行注入(赋值)【推荐】 4. JavaEE规范中类似功能的注解 JSR250 @Resource(name="userDAOImpl")基于名字进行注入 @Autowired() @Qualifier("userDAOImpl") 注意:如果在应用Resource注解时,名字没有配对成功,那么他会继续按照类型进行注入 JSR330 @Inject 作用 @Autowired完全一致 基于类型进行注入 ---> EJB3.0 <dependency> <groupId>java.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency> -
JDK类型
@Value注解完成 1. 设置xxxx.properties id = 10 name = suns 2. Spring的工厂读取这个配置文件 <context:property-placeholder location=""/> 3. 代码 属性@value("${key}")-
@PropertySource
1. 作用:用于替换Spring配置文件中的<context:property-placeholder location=""/> -
@Value注解使用细节
- @Value注解不能应用在静态成员变量上
- @Value注解+properties方式,不能应用在集合成员变量上
-
3、注解扫描详解
<context:component-scan base-package="com.bai"/>
当前包及其子包
-
排除方式
<context:component-scan base-package="coom.bai"> <context:exclude-filter type="" expression=""/> type:assignable:排除特定的类型 不进行扫描 annotation:排除特定的注解 不进行扫描 aspectj:切入点表达式 包切入点:.com.bai.bean..* 类切入蒂娜:*..User regex:正则表达式 custom:自定义排除策略 框架底层开发 </context:component-scan> 排除策略是可以叠加使用的 -
包含方式
<context:component-scan base-package="com.bai" user-default-filters="false"> <context:include-filter type="" expression=""/> </context:component-scan> 1.use-default-filters="false" 作用:让Spring默认的注解扫描方式失效 2.<context:include-filter type="" expression=""/> 作用:扫描指定的注解 type:assignable:扫描特定的类型 annotation:扫描特定的注解 aspectj:切入点表达式 包切入点:.com.bai.bean..* 类切入蒂娜:*..User regex:正则表达式 custom:自定义排除策略 框架底层开发 包含的方式支持叠加
4、对于注解开发的思考
-
配置互通
注解和配置文件可以互通 -
什么情况下使用注解,什么情况下使用配置文件
5、SSM整合开发(半注解)
第三章 Spring的高级注解(Spring3.x版本以上)
1、配置Bean
Spring在3.x提供的新的注解,用于替换XML配置文件
@Configuration
public class AppConfig{
}
-
配置Bean在应用的过程中,替换了XML具体的什么内容?
替换了ApplicationContext.xml的全部工作 -
AnnotationConfigApplicationCotext
1. 创建工厂代码 ApplicationContext ctx = new AnnotationConfigApplicationCotext(); 2. 指定配置文件 1.指定配置Bean的class ApplicationContext ctx = new AnnotationConfigApplicationCotext(AppConfig.class); 2.指定配置Bean的所在路径 ApplicationContext ctx = new AnnotationConfigApplicationCotext("com.bai");
1、集成logback
-
引入相关jar包
<dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.3.0-alpha5</version> <scope>test</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.0-alpha1</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>2.0.0-alpha1</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.3.0-alpha5</version> </dependency> <dependency> <groupId>org.logback-extensions</groupId> <artifactId>logback-ext-spring</artifactId> <version>0.1.5</version> </dependency> -
引入logback的配置文件(logback.xml)
<?xml version="1.0" encoding="UTF-8"/> <configuration> <!--控制台输出--> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppenfer"> <encoder> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> </appender> <root level="DEBUG"> <appender-ref ref="STDOUT"/> </root> </configuration> -
@Configuration注解的本质
本质:也是@Component注解的衍生注解 可以应用<context:component-scan>进行扫描
2、@Bean注解
@Bean注解在配置bean中进行使用,等同于XML配置文件中的<bean>标签
1、@Bean注解的基本使用
-
对象的创建
1. 简单对象 直接能够通过new方式创建的对象 User UserService UserDAO 2. 复杂对象 不能通过new的方式直接创建的对象 Connection SqlSessionFactory@Configuration public class AppConfig{ /** *简单对象 */ @Bean public User user(){ return new User(); } /** *创建复杂对象 */ @Bean public Connection conn(){ Connection conn = null; try{ Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/sun?userSSL=false","root","123455"); }catch (ClassNotFoundException e){ e.printStackTrace(); }catch(SQLException e){ e.printStackTrace(); } return conn; } }-
@Bean注解创建复杂对象的注意事项
public Connection conn{ Connection conn = null; try{ ConnectionFactoryBean factoryBean = new ConnectionFactoryBean(); conn = factoryBean.getObject(); } catch (Exception e){ e.printStackTrace(); } return conn; }
-
-
自定义id值
@Bean("id") -
控制对象创建次数
@Bean @Scope("singleton|prototype") 默认值 singleton
2、@Bean注解的注入
-
用户自定义类型
@Bean public UserDAO userDAO(){ return new UserDAOImpl(); } @Bean public UserService userService(UserDAO userDAO){ UserServiceImpl userService = new UserServiceImpl(); userService.setUserDAO(userDAO); return userService; } // 简化写法 @Bean public UserService userService(){ UserServiceImpl userService = new UserServiceImpl(); userService.setUserDAO(userDAO()); return userService; } -
JDK类型的注入
@Bean public Customer customer(){ Customer customer = new Customer(); customer.setId(1); customer.setName("xxx"); return customer; }-
JDK类型注入的细节分析
如果直接在代码中进行set方法的调用,会存在耦合的问题 @Configuration @PropertySource("classpath:/init.properties") public class AppConfig{ @Value("${id}") private Integer id; @Value("${name}") private String name; @Bean public Customer cutomer(){ Customer customer = new Customer(); customer.setId(id); customer.setName(name); return customer; } }
-
3、@ComponentScan注解
@ComponenScan猪妹在配置bean中进行使用,等同于XML配置文件中的<context:component-scan>标签
目的:进行相关注解的扫描 (@Compomemt @Value...@Autowired)
1、基本使用
@Configuration
@ComponentScan(basePackages="com.bai.scan")
public class AppConfig{
}
等同于<context:component-scan base-package=""/>
2、排除、包含的使用
-
排除
<context:component-scan base-package="com.bai"> <context:exclude-filter type="assignable" expression="com.bai.bean.user"></context:exclude-filter> </context:component-scan> @ComponentScan(basePackage = "com.bai.scan", excludeFilters = {@ComponentScan.Filter(type=FilterType.ANNOTATION,value={Service.class}), @ComponentScan.Filter(Type=FilterType.ASPECTJ,pattern="*.user1")}) type = FilterType.ANNOTATION value .ASSIGNABLE_TYPE value .ASPECTJ pattern .REGEX pattern .CUSTOM value -
包含
<context:component-scan base-package="com.bai" use-default-filters="false"> <context:include-filter type="assignable" expression="com.bai.bean.user"></context:include-filter> </context:component-scan> @ComponentScan(basePackage = "com.bai.scan", useDefaultFilters= false, includeFilters = {@ComponentScan.Filter(type=FilterType.ANNOTATION,value={Service.class}), @ComponentScan.Filter(Type=FilterType.ASPECTJ,pattern="*.user1")}) type = FilterType.ANNOTATION value .ASSIGNABLE_TYPE value .ASPECTJ pattern .REGEX pattern .CUSTOM value
4、Spring工厂创建对象的多种配置方式
1、多种配置方式的应用场景
@Component 平常开发
@Bean 框架和别人的代码
<bean></bean> 整合旧的系统
2、配置优先级
@Component及其衍生注解 < @Bean < 配置文件bean标签
优先级高的配置 覆盖优先级低配置
-
解决基于注解进行配置的耦合问题
@Configurationo @ImportResource("applicationContext.xml") public class AppConfig{ @Bean public UserDAO userDAO(){ return new UserDAOImpl(); } } applicationContext.xml <bean id="userDAO" class="com.bai.injection.userDAOImplNew"/>
5、整合多个配置信息
-
为什么会有多个配置信息
拆分多个配置bean的开发,是一种模块化开发的形式,也体现了面向对象各司其职的设计思想 -
多配置信息的整合方式
- 多个配置Bean的整合
- 配置Bean与@Component相关注解的整合
- 配置Bean与SpringXML配置文件的整合
-
整合多种配置徐哟啊关注哪些要点
- 如何使多配置的信息汇总成一个整体
- 如何实现跨配置的注入
1、多配置Bean的整合
-
多配置的信息汇总
-
base-package进行多个配置Bean的整合
-
@Import
1. 可以创建对象 2. 多配置bean的整合 -
在工厂创建时,指定多个配置Bean的Class对象【了解】
ApplicationContext ctx = new AnnotationConfigApplicationConext(AppConfig1.class,Appconfig2.class);
-
-
跨配置进行注入
在应用配置Bean的过程中,不管使用哪种方式进行配置信息的汇总,其操作方式都是通过成员变量加入@Autowired注解完成 @Configuration @Import(AppConfig2.class) public class AppConfig1{ @Autowired private UserDAO userDAO; @Bean public UserService userService(){ UserServiceImpl userService = new UserServiceImpl(); userService.setUserDAO(userDAO); return userService; } } @Configuration public class AppConfig2{ @Bean public UserDAO userDAO(){ return new UserDAOImpl(); } }
2、配置Beanyu@Component相关注解的整合
@Component(@Repository)
public class UserDAOImpl implements UserDAO{
}
@Configuration
@ComponentScan("")
public class AppConfig2{
@Autowired
private UserDAO userDAO;
@Bean
public UserService userService(){
UserServiceImpl userService = new UserServiceImpl();
userService.setUserDAO(userDAO);
return userService;
}
}
ApplicationContext ctx = new AnnotationConfigApplicationConext(AppConfig3.class);
3、配置Bean与配置文件整合
1. 遗留系统的整合 2. 配置覆盖
public class UserDAOImpl implements UserDAO{
}
<bean id="userDAO" class="com.bai.injection.UserDAOImpl"/>
@Configuration
@ImportResource("applicationContext.xml")
public class Appconfig4{
@Autowired
private UserDAO userDAO;
@Bean
public UserService userService(){
UserServiceImpl userService = new UserServiceImpl();
userService.setUserDAO(userDAO);
return userService;
}
}
ApplicationContext ctx = new AnnotationConfigApplicationConext(AppConfig4.class);
6、配置Bean底层实现原理
Spring在配置Bean中加入了@Configuration注解后,底层就会通过Cglib的代理方式,来进行对象相关的配置、处理
7、四维开发一体的开发思想
-
什么是四维一体
Spring开发一个功能的4中形式,虽然开发方式不同,但是最终效果都是一样的 1. 基于schema 2. 基于特定功能注解 3. 基于原始<bean> 4. 基于@Bean注解
8、纯注解版AOP编程
-
搭建环境
1. 应用配置Bean 2. 注解扫描 -
开发步骤
1. 原始对象 @Service public class UserServiceImpl implements userService{ } 2. 创建切面类(额外功能、切入点、组装切面) 3. Spring的配置文件中 <aop:aspectj-autoproxy /> ----> EnableAspectjAuroProxy -
注解AOP细节分析
1. 代理创建方式的切换 JDK Cglib <aop:aspectj-autoproxy proxy-target-class=true|false /> @EnableAspectjAutoproxy(proxyTargetClass) 2. SpringBoot AOP的开发方式 @EnableAspectjAutoproxy 已经默认设置好了 1. 原始对象 2.创建切面类 Spring AOP 代理默认实现是JDK SpringBoot AOP 代理默认实现是Cglib
9、Spring框架中YML的使用
-
什么是YML
YML(YAML)是一种新形式的配置文件,比XML更简单,比Properties更强大 -
Properties进行配置问题
1. Properties表达过于繁琐,无法表达数据的内在联系 2. Properties无法表达对象,集合类选 -
YML语法简介
1. 定义yml文件 xxx.yml xxx.yaml 2. 语法 1. 基本语法 name:sun password:123455 2.对象概念 account: id:1 password:123456 3. 定义集合 service - 11111 - 22222 -
Spring与YML集成思路的分析
1. 准备yml配置文件 init.yml 2. 读取yml转换成Properties YamlPropertiesFactoryBean.setResources(yml的配置路径) new ClassPathResource(); YamlPropertiesFactoryBean.getObject() ---> Properties 3. 应用PropertySourcePlaceHolderConfigurer PropertySourcePlaceholderConfigurer.setProperties(); 4. 类中@Value注解 注入 -
Spring与YML集成编码
-
环境搭建
<!-- https://mvnrepository.com/artifact/org.yaml/snakeyaml --> <dependency> <groupId>org.yaml</groupId> <artifactId>snakeyaml</artifactId> <version>1.26</version> </dependency> 最低版本1.18 -
编码
1. 准备yml配置文件 2. 配置Bean中操作,完成YAML读取与PropertySourcePlacehlderConfigure的创建 @Bean public PropertySourcePlaceholderConfigurer congifurer(){ YamlPropertiesFactoryBean ymlPropertiesFactoryBean = new YamlPropertiesFactoryBean(); ymlPropertiesFactoryBean.setResources(new ClassPathReource("init.yml)); Properties properties = ymlPropertiesFactoryBean.getObject(); PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer(); configurer.setProperties(properties); return configurer; } 3. 类 加入 @Value注解
-
Spring与YML集成的问题
1. 集合处理的问题 SpringEL表达式解决 @Value("#{'${list}'.split(',')}") 2. 对象类型的YAML进行配置时,过于繁琐 @Value("$(account.name)") SpringBoot @ConfigurationProperties