11 Spring 高级注解编程
一,使用注解开发AOP
1.AOP开发的基本要素
根据之前的总结,动态代理开发有以下要素
- 原始对象
- 额外功能
- 切入点
那么在注解开发中,其中额外功能和切入点整合为了一个类
对注解开发AOP的总体描述:提供原始对象和切面类之后由配置Bean整合使用
2.开发步骤
1.提供原始对象
需要提供@Component及其衍生注解来创建出这个类提供给切面类
@Service
public class UserServiceImpl implements UserService {
@Override
public void register() {
System.out.println("UserServiceImpl.register");
}
@Override
public void login(String name, String password) {
System.out.println("UserServiceImpl.login");
}
}
2.切面类开发
要提供@Aspect注解指明这是切面类
同样需要提供@Component创建代理类
使用 @Around提供切入点表达式
其余实现和之前的一致
@org.aspectj.lang.annotation.Aspect
@Component
public class Aspect {
@Around("execution(* *(..))")
public Object Arround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("Aspect.Arround");
Object ret=proceedingJoinPoint.proceed();
return ret;
}
}
3.配置Bean的开发
必须指明了切面类和原始对象所在的地方然后才能被配置Bean创建出来
@EnableAspectJAutoProxy指明自动扫描代理,等同于配置文件的<aop:aspectj-autoproxy />
@Configuration
@ComponentScan(basePackages = "org.AnnotationProgramming.AOP")
@EnableAspectJAutoProxy
public class Appconfig_Aop {
}
4.运行
获取配置Bean的信息即可
@Test
//测试注解开发AOP
public void test14() {
ApplicationContext context = new AnnotationConfigApplicationContext(Appconfig_Aop.class);
UserService userService= (UserService) context.getBean("userServiceImpl");
userService.register();
userService.login("SY","123");
}
效果:
Aspect.Arround
UserServiceImpl.register
Aspect.Arround
UserServiceImpl.login
注意:不需要再次在配置Bean中编写创建原始对象的方法了
二,使用注解整合Mybatis
和之前的整合流程一致,只不过是变换成了注解
整合代码如下:
使用配置文件解决了耦合
@Configuration
@ComponentScan(basePackages = "")
@MapperScan(basePackages = "")
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;
}
//sqlsession的创建
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
//一组Mapper文件
sqlSessionFactoryBean.setTypeAliasesPackage(mybatisProperties.getTypeAliasesPackages());
//一个Mapper文件
//sqlSessionFactoryBean.setMapperLocations(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;
}
}
注意点:MapperLocations编码时通配的写法
依然可以使用/*Mapper.xml表示一个文件夹下面的所有Mapper文件
mybatisProperties代码如下(省略了SET/GET方法):
@Component
@PropertySource("classpath:mybatis.properties")
public class MybatisProperties {
@Value("${mybatis.driverClassName}")
private String driverClassName;
@Value("${mybatis.url}")
private String url;
@Value("${mybatis.username}")
private String username;
@Value("${mybatis.password}")
private String password;
@Value("${mybatis.typeAliasesPackages}")
private String typeAliasesPackages;
@Value("${mybatis.mapperLocations}")
private String mapperLocations;
}
三,使用注解开发事务
事务开发时使用aop开发的所以需要:
-
原始对象
并标注上@Transactional注解
事务属性就在这里指定
@Service @Transactional public class UserServiceImpl implements UserService { @Autowired private UserDAO userDAO; public UserDAO getUserDAO() { return userDAO; } public void setUserDAO(UserDAO userDAO) { this.userDAO = userDAO; } @Override public void register(User user) { userDAO.save(user); } }
-
事务额外功能
需要加上@EnableTransactionManagement
@Configuration
@EnableTransactionManagement
public class TransactionAutoConfiguration {
@Autowired
private DataSource dataSource;
//此处只是作为演示不必看内容
@Bean
public DataSourceTransactionManager dataSourceTransactionManager() {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(dataSource);
return dataSourceTransactionManager;
}
}
四,Spring5中YML的使用
1.YML是什么
YAML不是一种标记语言,通常以.yml,.yaml为后缀的文件,是一种直观的能够被电脑识别的数据序列化格式,并且容易被人类阅读,容易和脚本语言交互的,可以被支持YAML库的不同的编程语言程序导入,一种专门用来写配置文件的语言。
2.YML语法
- 大小写敏感
- 松散表示,java中对于驼峰命名法,可用原名或使用-代替驼峰,如java中的lastName属性,在yml中使用lastName或 last-name都可正确映射。
1.基本语法
k: v 表示键值对关系,冒号之后有一个空格
例如:
id: 32
name: SY
password: 123456
2.对象语法,或者是Map语法
使用空格的缩进表示层级关系,只要是左对齐的一列数据,都是同一个对象的
缩进时不允许使用Tab键,只允许使用空格
例如:
Info:
id: 32
name: SY
password: 123456
表示为一行为(元素依然带有空格):
Info: {id: 32,name: SY,password: 123456}
3.数组,集合,list,set
用- 值表示数组中的一个元素
例如:
Info:
-32
-SY
-123456
表示为一行为
Info:[32,SY,123456]
4.数组对象,list对象,set对象
Info:
- id: 32
name: SY
password: 123456
- id: 0
name: SYS
password: 123
- {id: 32,name: SY,password: 123456}
3.Java中使用
1.处理集合问题
YML内容如下:
Arrays: 'A,B,C'
java处理如下:
使用#而不是处理properties的$,使用split分割
@Value("#{'${arrays}'.split(',')}")
private String[] arrays;
2.处理普通的注入
YML内容如下:
id: 1
java处理如下:
@Value("#{'${id}')
private Integerid;
4.Spring和YML的整合
1.配置MAVEN
版本需要在1.18以上
<!-- https://mvnrepository.com/artifact/org.yaml/snakeyaml -->
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.29</version>
</dependency>
2.配置读取YML的工具
由于Spring无法直接读取YML所以需要把YML变为properties形式
@Bean
public PropertySourcesPlaceholderConfigurer configurer(){
//配置yamlPropertiesFactoryBean读取YML文件
YamlPropertiesFactoryBean yamlPropertiesFactoryBean=new YamlPropertiesFactoryBean();
yamlPropertiesFactoryBean.setResources(new ClassPathResource("init.yml"));
//使得Properties对象拿到转变的YML文件
Properties properties =yamlPropertiesFactoryBean.getObject();
//读取Properties文件
PropertySourcesPlaceholderConfigurer configurer =new PropertySourcesPlaceholderConfigurer();
configurer.setProperties( properties);
return configurer;
}
3.使用:
1.基本使用
和之前使用Properties一样,同样的方法注入(省略了SET和GET方法)
@Service
public class Info
{
@Value("${id}")
private String id;
@Value("${name}")
private String name;
}
使用的YML内容为:
id: 32
name: SY
2.配置形式为对象
使用的YML内容为:
Info:
id: 32
name: SY
注入值得时候得跟着改变,加上了对象
@Service
public class Info
{
@Value("${Info.id}")
private String id;
@Value("${Info.name}")
private String name;
}
3.配置形式为集合
使用的YML内容为:
Info:
id: 32
name: SY
lists: A,B,C
由于Properties不可以解析集合类型得数据,所以就使用EL表达式
@Service
public class Info
{
@Value("${Info.id}")
private String id;
@Value("${Info.name}")
private String name;
@Value("#{'${lists}'.split(',')}")
private List<String> list;
}