博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring注解驱动开发(二)
阅读量:3916 次
发布时间:2019-05-23

本文共 6066 字,大约阅读时间需要 20 分钟。

Spring注解驱动开发

自动装配

@Resource

特点:可以和@Autowired一样实现自动装配功能;默认是按照组件名称进行装配的;

不同点:没有能支持@Primary功能没有支持@Autowired(reqiured=false);

@Resource(name="bookDao2")private BookDao bookDao;

@Inject

特点:需要导入javax.inject的包,和Autowired的功能一样。

不同点:没有required=false的功能

@Injectprivate BookDao bookDao;

@Autowired

@Autowired可以标注的位置

1)标注在方法位置:Spring容器创建当前对象,就会调用方法,完成赋值。(@Bean+方法参数;参数从容器中获取;默认不写@Autowired效果是一样的,都能自动装配)

@Beanpublic Color color(Car car){
Color color = new Color(); color.setCar(car); return color;} @Autowired //标注在方法,Spring容器创建当前对象,就会调用方法,完成赋值;//方法使用的参数,自定义类型的值从ioc容器中获取public void setCar(Car car) {
this.car = car;}

2)标在构造器上:如果组件只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件还是可以自动从容器中获取

@Autowiredpublic Boss(Car car){
this.car = car; System.out.println("Boss...有参构造器");}

3)放在参数位置:spring容器自动完成参数的注入

public Boss(@Autowired Car car){
this.car = car; System.out.println("Boss...有参构造器");}

@Autowired、@Resource和@Inject的区别

1、@Autowired是Spring定义的

2、@Resource和@Inject都是java规范

Aware注入Spring底层组件

自定义组件想要使用Spring容器底层的一些组件 ,例如ApplicationContext,BeanFactory的等,可以通过实现xxxAware接口,Spring容器在创建对象的时候,会调用接口规定的方法注入相关组件。

@Componentpublic class Red implements ApplicationContextAware,BeanNameAware,EmbeddedValueResolverAware {
private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
// TODO Auto-generated method stub System.out.println("传入的ioc:"+applicationContext); this.applicationContext = applicationContext; } @Override public void setBeanName(String name) {
// TODO Auto-generated method stub System.out.println("当前bean的名字:"+name); } @Override public void setEmbeddedValueResolver(StringValueResolver resolver) {
// TODO Auto-generated method stub String resolveStringValue = resolver.resolveStringValue("你好 ${os.name} 我是 #{20*18}"); System.out.println("解析的字符串:"+resolveStringValue); }}

@profile

Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能

特点
1)加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中。默认是default环境
2)写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效
3)没有标注环境标识的bean在,任何环境下都是加载的;

@PropertySource("classpath:/dbconfig.properties")@Configurationpublic class MainConfigOfProfile implements EmbeddedValueResolverAware{
@Value("${db.user}") private String user; private StringValueResolver valueResolver; private String driverClass; @Bean public Yellow yellow(){
return new Yellow(); } @Profile("test") @Bean("testDataSource") public DataSource dataSourceTest(@Value("${db.password}")String pwd) throws Exception{
ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setUser(user); dataSource.setPassword(pwd); dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test"); dataSource.setDriverClass(driverClass); return dataSource; } @Profile("dev") @Bean("devDataSource") public DataSource dataSourceDev(@Value("${db.password}")String pwd) throws Exception{
ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setUser(user); dataSource.setPassword(pwd); dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/ssm_crud"); dataSource.setDriverClass(driverClass); return dataSource; } @Profile("prod") @Bean("prodDataSource") public DataSource dataSourceProd(@Value("${db.password}")String pwd) throws Exception{
ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setUser(user); dataSource.setPassword(pwd); dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/scw_0515"); dataSource.setDriverClass(driverClass); return dataSource; } @Override public void setEmbeddedValueResolver(StringValueResolver resolver) {
// TODO Auto-generated method stub this.valueResolver = resolver; driverClass = valueResolver.resolveStringValue("${db.driverClass}"); }}

AOP

步骤

1、导入aop模块;Spring AOP:(spring-aspects)
2、定义一个业务逻辑类(MathCalculator);在业务逻辑运行的时候将日志进行打印(方法之前、方法运行结束、方法出现异常,xxx)
3、定义一个日志切面类(LogAspects):切面类里面的方法需要动态感知MathCalculator.div运行到哪里然后执行;
4、通知方法:
前置通知(@Before):logStart:在目标方法(div)运行之前运行
后置通知(@After):logEnd:在目标方法(div)运行结束之后运行(无论方法正常结束还是异常结束)
返回通知(@AfterReturning):logReturn:在目标方法(div)正常返回之后运行
异常通知(@AfterThrowing):logException:在目标方法(div)出现异常以后运行
环绕通知(@Around):动态代理,手动推进目标方法运行(joinPoint.procced())
5、给切面类的目标方法标注何时何地运行(通知注解);
6、将切面类和业务逻辑类(目标方法所在类)都加入到容器中;
7、必须告诉Spring哪个类是切面类(给切面类上加一个注解:@Aspect)
8、给配置类中加 @EnableAspectJAutoProxy 【开启基于注解的aop模式】
在Spring中很多的 @EnableXXX;

/** * 切面类 * @Aspect: 告诉Spring当前类是一个切面类 */@Aspectpublic class LogAspects {
//抽取公共的切入点表达式 //1、本类引用 //2、其他的切面引用 @Pointcut("execution(public int com.atguigu.aop.MathCalculator.*(..))") public void pointCut(){
}; //@Before在目标方法之前切入;切入点表达式(指定在哪个方法切入) @Before("pointCut()") public void logStart(JoinPoint joinPoint){
Object[] args = joinPoint.getArgs(); System.out.println(""+joinPoint.getSignature().getName()+"运行。。。@Before:参数列表是:{"+Arrays.asList(args)+"}"); } @After("com.atguigu.aop.LogAspects.pointCut()") public void logEnd(JoinPoint joinPoint){
System.out.println(""+joinPoint.getSignature().getName()+"结束。。。@After"); } //JoinPoint一定要出现在参数表的第一位 @AfterReturning(value="pointCut()",returning="result") public void logReturn(JoinPoint joinPoint,Object result){
System.out.println(""+joinPoint.getSignature().getName()+"正常返回。。。@AfterReturning:运行结果:{"+result+"}"); } @AfterThrowing(value="pointCut()",throwing="exception") public void logException(JoinPoint joinPoint,Exception exception){
System.out.println(""+joinPoint.getSignature().getName()+"异常。。。异常信息:{"+exception+"}"); }}

AOP底层原理

1、@EnableAspectJAutoProxy注解

调用@Import(AspectJAutoProxyRegistrar.class):给容器中导入AspectJAutoProxyRegistrar,利用AspectJAutoProxyRegistrar自定义给容器中注册bean,给容器中注册一个AnnotationAwareAspectJAutoProxyCreator对象

2、AnnotationAwareAspectJAutoProxyCreator的继承与实现关系

继承实现关系
3、创建和注册AnnotationAwareAspectJAutoProxyCreator
创建和注册AnnotationAwareAspectJAutoProxyCreator
4、AnnotationAwareAspectJAutoProxyCreator作为后置处理器的作用
AnnotationAwareAspectJAutoProxyCreator作为后置处理器的作用
总结
总结

声明式事务

环境搭建

1、导入相关依赖

数据源、数据库驱动、Spring-jdbc模块
2、配置数据源
JdbcTemplate(Spring提供的简化数据库操作的工具)操作数据
3、给方法上标注 @Transactional 表示当前方法是一个事务方法
4、 @EnableTransactionManagement 开启基于注解的事务管理功能
5、配置事务管理器来控制事务;

@Beanpublic PlatformTransactionManager transactionManager()

原理

原理

转载地址:http://bfirn.baihongyu.com/

你可能感兴趣的文章
持续交付一:从开发到上线的环境
查看>>
使用 docker 构建分布式调用链跟踪框架skywalking
查看>>
深度探秘.NET 5.0
查看>>
Github Actions 中 Service Container 的使用
查看>>
天际数见数据质量巡检架构优化
查看>>
别在.NET死忠粉面前黑.NET5,它未来可期!
查看>>
Winform 进度条弹窗和任务控制
查看>>
部署Dotnet Core应用到Kubernetes(二)
查看>>
持续交付二:为什么需要多个环境
查看>>
简单理解线程同步上下文
查看>>
购票啦 | 2020中国.NET开发者峰会启动
查看>>
FreeSql接入CAP的实践
查看>>
浅析 EF Core 5 中的 DbContextFactory
查看>>
听说容器正在吃掉整个软件世界?
查看>>
使用WebBenchmark对webapi进行管理和性能测试
查看>>
持续交付三:动手自动化“开发”—>“测试”
查看>>
WebBenchmark动态测试Webapi
查看>>
Windows 7 安装 .NET 5 / .NET Core 3.1 环境的方法和依赖文件
查看>>
接口幂等设计探索实践
查看>>
微服务很香--麻辣味,但要慢慢消化
查看>>