Spring注解驱动(下)
9.@PropertySource 加载配置文件
在xml中 我们加载property配置文件,是使用
<context:property-placeholder location="classpath:spring-common.xml"/>
同样,使用注解的方式也同样可以完成
@PropertySource("classpath:jdbc.properties")//加载类路径下的jdbc.properties文件
public class PropertiesWithJavaConfig {}
10.@Autowired注解,自动装配
自动装配:
Spring利用依赖注入(DI),完成对IOC容器中各个组件的依赖关系赋值;
@Autowired:自动注入
- 默认优先按照类型从容器中找对应的组件,
applicationContext.getBean(BookDao.class)
- 如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找
applicationContext.getBean("bookDao")
- 结合
@Qualifier("bookDao")
实现在通过类型转配的同时,指定id,而不是根据属性名 - 自动装配时,如果没有找到,就会报错,可以使用
@Autowired(required=false)
属性,使用后,如果在装配时没有找到不会报错,而是null; @Primary
注解 让Spring 进行自动转配的时候 ,默认使用首选的Bean 标注@Bean
注解的方法即可,如果想要指定Bean时,则可以继续使用@Qualifier
来指定Bean的id
Spring还支持使用@Resource
(JSR250) 和@Inject
(JSR330) [java规范的注解]
@Resource
:
可以和Autowired注解一样实现自动装配,默认是按照组件名称进行装配的(有name属性),不支持@Primary
功能 不支持@Autowired(reqiured=false)
;
`@Inject`:
需要导入javax.inject 的包,和Autowired注解的功能一样,但是没有 required=false的功能
另外 , @Autowired
除了可以在方法上声明使用外,构造器上,形参上都可以声明 自动装配
11.实现xxxxAware接口 ,将Spring的容器注入到自己的类中
自定义组件想要使用Spring容器中的一些组件,例(ApplicationContext,BeanFactory..).自定义组件实现xxxAware; 在创建对象的时候 会调用接口的方法进行注入, 实现这个功能的是后置处理器,例如
ApplicationContextAware(注入ApplicationContext) ==> ApplicationContextAwareProcessor 处理器类
12. @Profile根据环境注册bean
不同的环境 ,需要注入不同的组件,就可以使用该注解,例如 在开发 测试 生产 时 注入的数据源就可能不一样,
例:
@PropertySource("classpath:/dbconfig.properties") //注入的配置文件位置
@Configuration
public 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") //标识为 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") //标识为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") //标识为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}");
}
}
上面的案例中,将三个数据源标识了三个标识,在对应的标识被激活时 才会注入这些对象,如果不指定,就是"default"环境.
如果环境标识注解写在类上,只有对应的环境被激活,整个配置类的Bean才会被加载.
没有标注环境标识的bean 在任何环境下都会被加载.
指定环境的方式.
使用命令行动态参数:在虚拟机参数位置加载 -Dspring.profiles.active=test.
代码的方式激活某种环境.
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext();
//1、创建一个applicationContext
//2、设置需要激活的环境
applicationContext.getEnvironment().setActiveProfiles("dev");
//3、注册主配置类
applicationContext.register(MainConfigOfProfile.class);
//4、启动刷新容器
applicationContext.refresh();
13. AOP基于注解的使用
spring中的aop是非常重要的功能,底层基于动态代理,可以使用xml的配置方式使用,同样也可以使用注解的方式完成:
导入aop模块 Spring AOP(spring-aspects)
定义一个业务逻辑类 ;在业务逻辑运行时讲日志进行打印
定义一个日志切面类,切面类里面的方法需要动态感知业务逻辑类运行到哪里然后执行
相关注解:
前置通知
@Before
:在目标方法运行前执行后置通知
@After
:在目标方法运行结束之后执行(无论方法正常结束还是异常结束)返回通知
@AfterReturning
: 在目标方法正常返回之后运行异常通知
@AfterThrowing
:在目标方法出现异常以后运行环绕通知
@Around
:动态代理,手动推进目标方法运行给切面类的目标方法标注何时何地执行(切入点表达式
@Pointcut
)将切面类和业务逻辑类都注入到容器中
给切面类加一个注解:
@Aspect
(告诉Spring那个类是切面类)给配置类中加一个注解
@EnableAspectJAutoProxy
开启基于注解的aop模式@Aspect
public 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+"}");
} }
14 Spring 事务基于注解的使用
同样Spring对于事务的控制,也可以使用注解来完成
导入 相关依赖: 数据源,数据库驱动, Spring-jdbc 模块
配置数据源
给方法上标注
@Transactional
表示当前方法是一个事务方法@EnableTransactionManagement
开启基于注解的事务管理器配置事务管理器来控制事务
@Bean
public PlatformTransactionManager transactionManager()
15 注解式监听器@EventListener
在spring中可以实现ApplicationListener<ApplicationEvent>
接口来实现对事件的监听,泛型为监听的事件对象, 所有的事件对象都是ApplicationEvent
的子类,所以该实现类就是监听所有的事件
同样,也可以使用的注解的方式,来指定一个方法 去监听指定的事件,例:
@Service
public class UserService {
@EventListener(classes={ApplicationEvent.class})
public void listen(ApplicationEvent event){
System.out.println("UserService。。监听到的事件:"+event);
}
}
该例就是让该方法去监听所有的事件
Spring注解驱动(下)的更多相关文章
- 【Spring注解驱动开发】聊聊Spring注解驱动开发那些事儿!
写在前面 今天,面了一个工作5年的小伙伴,面试结果不理想啊!也不是我说,工作5年了,问多线程的知识:就只知道继承Thread类和实现Runnable接口!问Java集合,竟然说HashMap是线程安全 ...
- 【Spring注解驱动开发】组件注册-@ComponentScan-自动扫描组件&指定扫描规则
写在前面 在实际项目中,我们更多的是使用Spring的包扫描功能对项目中的包进行扫描,凡是在指定的包或子包中的类上标注了@Repository.@Service.@Controller.@Compon ...
- 【Spring注解驱动开发】自定义TypeFilter指定@ComponentScan注解的过滤规则
写在前面 Spring的强大之处不仅仅是提供了IOC容器,能够通过过滤规则指定排除和只包含哪些组件,它还能够通过自定义TypeFilter来指定过滤规则.如果Spring内置的过滤规则不能够满足我们的 ...
- 【Spring注解驱动开发】使用@Scope注解设置组件的作用域
写在前面 Spring容器中的组件默认是单例的,在Spring启动时就会实例化并初始化这些对象,将其放到Spring容器中,之后,每次获取对象时,直接从Spring容器中获取,而不再创建对象.如果每次 ...
- 【Spring注解驱动开发】使用@Lazy注解实现懒加载
写在前面 Spring在启动时,默认会将单实例bean进行实例化,并加载到Spring容器中.也就是说,单实例bean默认在Spring容器启动的时候创建对象,并将对象加载到Spring容器中.如果我 ...
- 【Spring注解驱动开发】使用@Import注解给容器中快速导入一个组件
写在前面 我们可以将一些bean组件交由Spring管理,并且Spring支持单实例bean和多实例bean.我们自己写的类,可以通过包扫描+标注注解(@Controller.@Servcie.@Re ...
- 【Spring注解驱动开发】在@Import注解中使用ImportSelector接口导入bean
写在前面 在上一篇关于Spring的@Import注解的文章<[Spring注解驱动开发]使用@Import注解给容器中快速导入一个组件>中,我们简单介绍了如何使用@Import注解给容器 ...
- 【Spring注解驱动开发】面试官:如何将Service注入到Servlet中?朋友又栽了!!
写在前面 最近,一位读者出去面试前准备了很久,信心满满的去面试.没想到面试官的一个问题把他难住了.面试官的问题是这样的:如何使用Spring将Service注入到Servlet中呢?这位读者平时也是很 ...
- 【Spring注解驱动开发】在@Import注解中使用ImportBeanDefinitionRegistrar向容器中注册bean
写在前面 在前面的文章中,我们学习了如何使用@Import注解向Spring容器中导入bean,可以使用@Import注解快速向容器中导入bean,小伙伴们可以参见<[Spring注解驱动开发] ...
随机推荐
- 十个非常实用的MySQL命令
建赟 版主 楼主 前言 今天介绍一些MySQL常用的实用命令,都是一些比较简单的命令.已经知道的朋友,就当是巩固吧,不知道的童鞋,可以好好在自己的机器上,练习下. 0. 显示数据库 命令:s ...
- 找到你的位置(JS在页面中的位置)最常用的方式是在页面中head部分放置<script>元素,浏览器解析head部分就会执行这个代码,然后才解析页面的其余部分
找到你的位置(JS在页面中的位置) 我们可以将JavaScript代码放在html文件中任何位置,但是我们一般放在网页的head或者body部分. 放在<head>部分 最常用的方式是在页 ...
- RAksmart服务器具备哪些特点?
美国RAKsmart机房运营多年,前身是提供美国军用服务器业务,拥有着庞大的用户群体和消费者,那RAksmart服务器具备哪些特点呢? 1.美国raksmart服务器特点——硬盘超大 美国raksma ...
- CI的session操作
在使用session之前,要对配置文件config.php 里面的$config['encryption_key']随便赋个值,例如1234 1. 首先要加载session类,固定写法:$this-& ...
- Bubble Cup 12 - Finals [Online Mirror, unrated, Div. 1] E. Product Tuples
题意略,题解生成函数练习题,1+(q-ai)x卷积即可,线段树优化(类似分治思想) //#pragma GCC optimize(2) //#pragma GCC optimize(3) //#pra ...
- C# .net async await 学习
async/await简单介绍 在处理比较耗时的操作(如图片处理.数据压缩.http请求等)传统的异步方法是直接使用Thread或者Task进行操作,在复杂的应用编写中可能会出现回调的问题,因此C#目 ...
- System.String.cs
ylbtech-System.String.cs 1.程序集 mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c5619 ...
- Activity详解一 配置、启动和关闭activity转载 https://www.cnblogs.com/androidWuYou/p/5887726.html
先看效果图: Android为我们提供了四种应组件,分别为Activity.Service.Broadcast receivers和Content providers,这些组建也就是我们开发一个And ...
- java_JDK8中新增的时间API
java.time 包含值对象的基础包 java.time.chrono 提供对不同的日历系统的访问 java.time.format 格式化和解析时间的日期 java.time.temporal 包 ...
- lxml etree对存在的xml添加新节点,新节点没有排版格式化
新添加的时候如果不做处理,是这个样子 要在解析xml加上 parser = etree.XMLParser(remove_blank_text=True)xml = etree.parse(major ...