一、配置Bean @Configuration
Spring在3.x提供的注解,用于替换XML配置文件。
@Configuration
public class AppConfig{}
AnnotationConfigApplicationContext
1.创建工厂代码
ApplicationContext app = new AnnotationConfigApplicationContext();
2.指定配置文件
1.指定配置bean的Class
ApplicationContext app = new AnnotationConfigApplicationContext(AppConfig.class);
2.指定配置bean所在的路径
ApplicationContext app = new AnnotationConfigApplicationContext(“com.bao.bean”);
配置Bean开发的细节分析
1.基于注解开发使用日志
不能集成Log4j,取而代之的是logback。
引入相关jar包:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.10</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.10</version>
</dependency>
<dependency>
<groupId>org.logback-extensions</groupId>
<artifactId>logback-ext-spring</artifactId>
<version>0.1.4</version>
</dependency>
引入logback配置文件:
logback.xml:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd' 'HH:mm:ss.sss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
2.@Configuration注解的本质
本质:也是@Component注解的衍生注解
也可以应用<context:component-scan>进行扫描
二、@Bean注解
@Bean注解在配置bean中进行使用,等同于XML配置文件中的<bean>标签
1.@Bean注解的基本使用
对象的创建
1.简单对象
可以直接new的对象
2.复杂对象
不可直接new的对象
@Bean注解创建复杂对象的注意事项
FactoryBean与@Bean的联合使用(遗留系统整合)
public class ConnectionFactoryBean implements FactoryBean<Connection> {
public Connection getObject() throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?useSSL=false","root","123456");
return conn;
}
public Class<?> getObjectType() {
return Connection.class;
}
public boolean isSingleton() {
return false;
}
}
@Bean
public Connection conn1(){
Connection conn = null;
try {
ConnectionFactoryBean factoryBean = new ConnectionFactoryBean();
conn = factoryBean.getObject();
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
自定义id值
@Bean("u")
控制对象的创建次数
@Bean @Scope("singleton|prototype")
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(50);
customer.setName("李星云");
return customer;
}
引入properties配置文件解决耦合:
init.properties:
id = 50
name = 李星云
@Configuration
@PropertySource(value = "classpath:init.properties",encoding = "UTF-8")
public class AppConfig1 {
@Value("${id}")
private int id;
@Value("${name}")
private String name;
3.@ComponentScan注解
@ComponentScan注解在配置bean中进行使用,等同于xml配置文件中的<context:component-scan>标签
目的:进行相关注解扫描
基本使用
@Configuration @ComponentScan(basePackages = "com.bao.scan") public class AppConfig2 { } 等价于<context:component-scan base-package=""/>
排除、包含是使用(五种type类型,见基础注解)
排除(可叠加):
@Configuration
@ComponentScan(basePackages = "com.bao.scan",
excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Service.class}),
@ComponentScan.Filter(type = FilterType.ASPECTJ,pattern = {"com.bao..*"})}})
public class AppConfig2 {
}type = FilterType.ANNOTATION value
.ASSIGNABLE_TYPE value
.ASPECTJ pattern
.REGEX pattern
.CUSTOM value
包含(可叠加):
@Configuration @ComponentScan(basePackages = "com.bao.scan", includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Service.class}), @ComponentScan.Filter(type = FilterType.ASPECTJ,pattern = {"com.bao..*"})}}) public class AppConfig2 { } type = FilterType.ANNOTATION value .ASSIGNABLE_TYPE value .ASPECTJ pattern .REGEX pattern .CUSTOM value
4.Spring工厂创建对象的多种配置方式
多种配置方法的应用场景:
@Component及其衍生注解 程序员自己开发的类型
@Bean 框架提供的类型,其他程序员开发的类型(没有源码)
<bean id="user" class=""/> 纯注解开发基本不用,遗留系统整合使用
@Import 1.Spring框架底层使用 2.多配置Bean整合
配置优先级
@Component及其衍生注解 < @Bean < <bean id="user" class=""/> 优先级高的配置 覆盖优先级低配置 @ComponentScan与配置文件<bean>标签整合 ---->@ImportResource("applicationContext.xml") 覆盖,可以解决基于注解进行配置的耦合问题
5.多个配置Bean的整合
⚪多配置的信息汇总
base-package进行多个配置Bean的整合
@Configuration
public class AppConfig1 {
@Bean
public UserService userService(){
UserServiceImpl userService = new UserServiceImpl();
return userService;
}
}
@Configuration
public class AppConfig2 {
@Bean
public UserDAO userDAO(){
UserDAOImpl userDAO = new UserDAOImpl();
return userDAO;
}
}
ApplicationContext app = new AnnotationConfigApplicationContext("com.bao.config");
UserDAO userDAO = (UserDAO) app.getBean("userDAO");
UserService userService = (UserService) app.getBean("userService");
@import进行多个配置Bean的整合
@Configuration
@Import(AppConfig2.class)
public class AppConfig1 {
@Bean
public UserService userService(){
UserServiceImpl userService = new UserServiceImpl();
return userService;
}
}
ApplicationContext app = new AnnotationConfigApplicationContext(com.bao.config.AppConfig1.class);
UserDAO userDAO = (UserDAO) app.getBean("userDAO");
UserService userService = (UserService) app.getBean("userService");
System.out.println(userDAO);
System.out.println(userService);
在工厂创建时,指定多个配置Bean的Class对象
ApplicationContext app = new AnnotationConfigApplicationContext(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;
}
}
配置Bean与@Component相关注解的整合
@Component
public class UserDAOImpl implements UserDAO{
}
@Configuration
@ComponentScan(basePackages = "com.bao.injection)
public class AppConfig3 {
@Bean
public UserService userService(){
UserServiceImpl userService = new UserServiceImpl();
return userService;
}
}
ApplicationContext app = new AnnotationConfigApplicationContext(AppConfig3.class);
UserDAO userDAO = (UserDAO) app.getBean("userDAOImpl");
配置Bean与配置文件整合
1.遗留系统整合 2.配置覆盖
public class UserDAOImpl implements UserDAO{
}
applicationContext.xml:
<bean id="userDAO" class="com.bao.injection.UserDAOImpl"/>
@Configuration
@ImportResource("applicationContext.xml")
public class AppConfig4 {
@Bean
public UserService userService(){
UserServiceImpl userService = new UserServiceImpl();
return userService;
}
6.配置Bean底层实现原理
@Configuration 实际上AOP方式进行开发(cglib)
7.四维一体的开发思想
1.什么是四维一体
Spring开发一个功能的4种形式,虽然开发方式不同,但是最终效果是一样的。
1.基于schema <context:
2.基于特定功能注解
3.基于原始<bean>
<bean id="pro" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="location" value="classpath:init.properties"/>
</bean>
4.基于@Bean注解
2.四维一体开发案例
<context:property-placehoder
@PeopertySource [推荐]
<bean id="" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"/>
@Bean [推荐]
8.纯注解版AOP编程
搭建环境
1.应用配置Bean @Configuration 2.注解扫描 @ComponentScan("basePackages = "com.bao.injection"")
开发步骤
1.原始对象
@Service
public class UserServiceImpl implements UserService{
}
2.创建切面类 (额外功能 切入点 组装切面)
@Aspect
@Component
public class MyAspect {
@Around("execution(* login(..))")//切入点
public Object arround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("---切面类log---");
Object ret = joinPoint.proceed();//原始方法运行
return ret;
}
}
3.Spring配置文件中
//<aop:aspectj-autoproxy />
@EnableAspectjAutoProxy
@Configuration
@ComponentScan(basePackages = "com.bao.aop")
@EnableAspectjAutoProxy
public class AppConfig{
}
注解AOP细节分析
1.代理创建方式的切换 JDK Cglib
<aop:aspectj-autoproxy proxy-target-class=true|false />
@EnableAspectjAutoProxy(proxyTargetClass = true|false)
2.SpringBoot AOP开发方式
//@EnableAspectjAutoProxy 默认设置好了
1.原始对象
@Service
public class UserServiceImpl implements UserService{
}
2.创建切面类 (额外功能 切入点 组装切面)
@Aspect
@Component
public class MyAspect {
@Around("execution(* login(..))")//切入点
public Object arround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("---切面类log---");
Object ret = joinPoint.proceed();//原始方法运行
return ret;
}
}
Spring AOP代理默认实现 JDK
SpringBOOT AOP代理默认实现 Cglib
9.纯注解Spring+MyBatis整合
基础配置(配置Bean)
spring配置文件回顾:
配置文件(ApplicationContext.xml)进行相关配置
<bean id="dataSource" class=""/>
创建SqlSessionFactory:
<bean id="ssfb" class="SqlSessionFactoryBean">
<property name="dataSource" ref=""/>
<property name="typeAliasesPackage">
指定 实体类所在的包
</property>
<property name="mapperLocations">
指定 映射文件的路径 还有通用配置
com.bao,maooer/*Mapper.xml
</property>
</bean>
DAO接口的实现类:
<bean id="scanner" class="MapperScannerConfigure">
<property name="SqlSessionFactoryBeanName" value="ssfb"/>
<property name="basePacakge">
指定 DAO接口放置的包
</property>
</bean>
------------------------------------------------------------------------
1.连接池
@Bean
public DruidDataSource dataSource(){
DriidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("");
dataSource.setUrl();
dataSource.setUsername();
dataSource.setPassword();
return dataSource;
}
2.SqlSessionFactoryBean
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setTypeAliasesPackage("com.bao.mybatis");
//设置Mapper文件路径
//sqlSessionFactoryBean.setMapperLocations(new ClassPathResource[]{new ClassPathResource("*Mapper.xml")});
try {
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources("classpath*:*Mapper.xml");
sqlSessionFactoryBean.setMapperLocations(resources);
} catch (IOException e) {
e.printStackTrace();
}
return sqlSessionFactoryBean;
}
3.MapperScannerConfigure
@MapperScan(basePackage={"com.bao.dao"}) --->配置bean
编码:
1.实体
public class User implements Serializable {
private int id;
private String name;
private String password;
public User() {
}
public User(int id, String name, String password) {
this.id = id;
this.name = name;
this.password = password;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
2.表(略)
3.DAO接口
public interface UserDAO {
public void save(User user);
}
4.Mapper文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bao.mybatis.UserDAO">
<insert id="save" parameterType="User">
insert into t_users(name,password) values (#{name},#{password})
</insert>
<delete id="delete" parameterType="User">
delete from t_users where id=#{id}
</delete>
</mapper>
配置Bean注解耦合
driverClassName = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/mybatis?useSSL=false
username = root
password = 123456
typeAliasesPackage = com.bao.mybatis
mapperLocations = classpath*:com.bao.mapper/*Mapper.xml
@Component
@PropertySource(value = "classpath:init.properties",encoding = "UTF-8")
public class MybatisProperties {
@Value("${driverClassName}")
private String driverClassName;
@Value("${url}")
private String url;
@Value("${username}")
private String username;
@Value("${password}")
private String password;
@Value("${typeAliasesPackage}")
private String typeAliasesPackage;
@Value("${mapperLocations}")
private String mapperLocations;
//配置Bean注入
@Configuration
@ComponentScan(basePackages = "com.bao.mybatis")
@MapperScan(basePackages = "com.bao.mybatis")
public class MybatisAutoConfiguration {
@Autowired
private MybatisProperties mybatisProperties;
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(mybatisProperties.getDriverClassName());
dataSource.setUrl(mybatisProperties.getUrl());
dataSource.setUsername(mybatisProperties.getUsername());
dataSource.setPassword(mybatisProperties.getPassword());
return dataSource;
}
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setTypeAliasesPackage(mybatisProperties.getTypeAliasesPackage());
//sqlSessionFactoryBean.setMapperLocations(new ClassPathResource[]{new ClassPathResource("UserDAOMapper.xml")});
try {
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources(mybatisProperties.getMapperLocations());
sqlSessionFactoryBean.setMapperLocations(resources);
} catch (IOException e) {
e.printStackTrace();
}
return sqlSessionFactoryBean;
}
}
10.纯注解的事务编程
1.原始对象 XXXService
<bean id="userService" class="com.bao.mybatis.service.UserServiceImpl">
<!--注入DAO,ref="userDAO"源自于MapperScannerConfigure-->
<property name="userDAO" ref="userDAO"></property>
</bean>
-----------------------------------------------------------------------
@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserDAO userDAO;
}
2.额外功能
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入连接池-->
<property name="dataSource" ref="dataSource"></property>
</bean>
-----------------------------------------------------------------------
@Bean
public DataSourceTransactionManager dataSourceTransactionManager(DataSource dataSource){
DataSourceTransactionManager dstm = new DataSourceTransactionManager();
dstm.setDataSource(dataSource);
return dstm;
}
3.事务属性
@Transactional//切入点:类中所有的方法都会加入事务
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDAO userDAO;
4.基于Schema的事务配置
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"></tx:annotation-driven>
-----------------------------------------------------------------------
@EnableTransactionManager //配置Bean中完成 自动扫描dataSourceTransactionManager
Spring框架中YML的使用
什么是YML
YML(YAML)是一种新形式的配置文件,比XML更简单,Properties更强大。
Properties进行配置问题
Properties表达过于繁琐,无法表达数据的内在联系。 Properties无法表达对象 集合类型
YML语法简介
1.定义yml文件
xxx.yml xxx.yaml2.语法
1.基本语法
name:chenbao
password:1234
2.对象概念
accout:
id:1
password:1234
3.定义集合
service:
- 111
- 222
Spring与YML集成思路分析
Spring提供的 YamlPropertiesFactoryBean 读取 YML 1.准备yml配置文件 init.yml name:chen password:1234 2.读取yml 转换成 Properties YamlPropertiesFactoryBean.setResources(yml配置文件路径) new ClassPathResource(); YamlPropertiesFactoryBean.getObject(); --->返回Properties 3.应用PropertySourcePlaceholderConfigurer.setProperties(); 4.类中应用@Value注解注入
Spring与YML集成编码
环境搭建
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.26</version>
</dependency>
最低版本 1.18
编码
1.准备yml配置文件
chen:
name: chenbao
password: 1234
2.配置Bean中操作 完成YAML读取 与 PropertySourcePlaceholaerConfigure的创建
@Configuration
@ComponentScan(basePackages = "com.bao.yml")
public class YmlAutoConfiguration {
@Bean
public PropertySourcesPlaceholderConfigurer configurer(){
YamlPropertiesFactoryBean yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean();
yamlPropertiesFactoryBean.setResources(new ClassPathResource("init.yml"));
Properties properties = yamlPropertiesFactoryBean.getObject();
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
configurer.setProperties(properties);
return configurer;
}
}
3.类 加入 @Value注解
@Component
public class Account {
@Value("${chen.name}")
private String name;
@Value("${chen.password}")
private String password;
Test:
public void test3(){
ApplicationContext app = new AnnotationConfigApplicationContext(YmlAutoConfiguration.class);
Account account = (Account) app.getBean("account");
System.out.println(account.getName());
System.out.println(account.getPassword());
}
Spring与YML集成的问题
1.集合处理的问题 SpringEL表达式解决: list: 111,222 @Value("#{'${list}'.split(',')}") private List<String> list; 2.对象类型的YAML进行配置时 过于繁琐 @Value("${chen.name}")和@Value("${chen.password}") 解决:SpringBooT--->@ConfigurationProperties