spring注解开发,ioc和id
- 给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id。
- @Configuration
- @Bean(“name”)设置id
- @ComponentScan({“com.chen”})
- excludeFilters={@Filter(type=FilterType.ANNOTATION,classes={Controller.class,Service.class})};排除
- includeFilters={@Filter(type=FilterType.ANNOTATION,classes={Controller.class})} 包含
- @Filter(type=FilterType.ASSIGNABLE_TYPE,classes={TxConfig.class,UserDao.class,UserService.class}),查找具体的类
- @Filter(type=FilterType.CUSTOM,classes={MyTypeFilter.class});自定义过滤器
- @ComponentScans
- Value是ComponentScan数组
- @Scope
- prototype:多实例,ioc容器启动并不会去调用方法创建对象到容器,只有获取时才创建。
- singleton:ioc容器启动会调用方法创建对象放到ioc容器中;以后没吃获取都从容器中拿
- request
- session
- 懒加载;@Lazy
- 单实例bean,默认在容器启动的时候创建对象;
- 懒加载:容器启动时不创建对象,获取bean时创建对象
- @Conditional({Condition}):按照一定的条件进行判断,满足条件给容器中注册bean
- 放在方法上
- 自定义一个类实现Condition接口
/**
* ConditionContext:判断条件,能使用的上下文
* AnnotatedTypeMetadata:注解信息
*/
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//判断是否是linux系统
//1.获取到ioc使用的beanfactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
//2.获取类加载器
ClassLoader classLoader = context.getClassLoader();
//3.获取当前环境信息
Environment environment = context.getEnvironment();
//4.获取bean定义的注册类
BeanDefinitionRegistry registry = context.getRegistry();
//可以判断容器中的bean注册情况,也可以给容器中注册bean
boolean definition = registry.containsBeanDefinition("person");
String pString = environment.getProperty("os.name");
if(pString.contains("linux")){
return true;
}
return false;
}
- @Conditional放在配置类上,满足当前条件,这个类中配置的所有bean注册才能生效
- 给容器中注册组件
- 包扫描+组件标注注解(@Controller,@Service,@Component)
- @Bean[导入的第三方包里面的组件]
- @Import[快速给容器中导入一个组件]
- @Import:快速导入组件,id默认时组件全类名
- @Import({Color.class,Red.class})
- ImportSelector:返回需要导入的组件的全类名数组
/**
*@author chenmin
*@version 创建时间:2020年8月27日 下午4:06:10
*AnnotationMetadata:当前标注@Import注解的类上所有注解信息
*
*/
public class MyImportSelector implements ImportSelector {
//返回值,就是到导入到容器中的组件全类名
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.chen.bean.Blue","com.chen.bean.Yellow"};
}
}
-
- ImportBeanDefinitionRegistrar
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar{
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean definition = registry.containsBeanDefinition("com.chen.bean.Red");
boolean definition2 = registry.containsBeanDefinition("com.chen.bean.Blue");
if(definition && definition2){
//指定bean名
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(RainBow.class);
registry.registerBeanDefinition("rainBow", rootBeanDefinition);
}
}
}
- 使用spring提供的FactoryBean接口
- Bean创建---初始化---销毁的过程
- 容器管理bean的生命周期:我们可以自定义初始化和销毁方法
- 构造(对象创建)
- 单实例:在容器启动的时候创建bean
- 多实例:在每次获取的时候创建bean
- 指定初始化和销毁方法
@Bean(initMethod="init",destroyMethod="destory")
public Car car(){
return new Car();
}
-
- 初始化:对象完成创建,并赋值,调用初始化方法
- 销毁
- 单实例:容器关闭,调用销毁方法
- 多实例:容器关闭,容器不会管理bean,容器不会调用销毁方法
- 通过Bean实现InititalizingBean接口来定义初始化,DisposableBean接口实现销毁
public class Cat implements InitializingBean,DisposableBean{
public Cat() {
System.out.println("cat....constructor....");
}
public void destroy() throws Exception {
System.out.println("cat....destory....");
}
public void afterPropertiesSet() throws Exception {
System.out.println("cat....afterPropertiesSet....");
}
}
- 使用JSR250
- @PostConstruct,初始化,在bean创建完成并且属性赋值完成,来执行初始化方法
@PostConstruct
public void init(){
System.out.println("dog....init....");
}
-
- @PreDestory,销毁,在容器销毁bean之前,通知销毁
@PreDestory
public void destory(){
System.out.println("dog....destory....");
}
- BeanPostProcessor接口,bean的后置处理器,在bean初始化前后进行一些处理工作
- populateBean(beanName,mbd,instanceWrapper);给属性赋值
- 遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization
-
- postProcessBeforeInitialization
- invokeInitMethods(beanName, wrappedBean, mb;初始化方法
- postProcessAfterInitialization
- @Value
- 基本数值:
- 可以写SpEL,#{20-2}
- ${},取出配置文件中的值(在运行环境)
${}配合@PropertySource("classpath:person.properties")使用,该注解放在配置类上
- 自动装配
- Spring利用依赖注入(DI)完成对IOC容器中各个组件的依赖关系赋值
- @Autowired,自动注入
- 默认优先按照类型去容器中找对应的组件
- 如果找到多个相同类型组件,再将属性的名称作为组件id去容器中查找
- @Qualifier("bookDao")
使用指定装配的组件id,而不是使用属性名。如下图
-
- @Autowired自动装配默认一定要将属性赋值好,没有就会报错,设置@Autowired(required=false),这样就不会报错了。
- @Primary:让spring进行自动装配的时候,默认使用首选的bean,首选使用bookDao2,如下图:
-
- 也可以继续使用@Qualifier(“bookDao”)指定装配
- Spring还支持@Resource(JSR250)和@Inject(JSR330)java规范注解
- @Resource:按照组件的名称进行装配
- @Inject:可以和@Primary结合使用,但要导入javax.inject这个包,和@Autowired一样
- @Autowired可以标注构造器,方法,属性参数;标在构造器上:如果组件只有一个参数构造器,这个有参构造器@Autowired可以省略,参数位置的组件可以从容器中获取
- 自定义组件想要使用spring容器底层的一些组件(ApplicationContext,BeanFactory)自定义组件实现xxxAware.
- @Profile
- 指定组件在那个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件
- 加了环境标识的bean,只有这个环境被**的时候才能注册到容器中,默认是default环境
- @Profile可以加在配置类上,也可以在注册方法上
- 手动修改运行环境:
- 声明式事务
- 环境搭建
1.导入相关依赖
数据源,数据库驱动,spring-jdbc
2.配置数据源,jdbcTemplate操作数据库
3.给方法上标注@Transactional注解
4.给配置类标注@EnableTransactionManagement
5.将事务管理器添加到容器中
-
- 原理
* 利用TransactionManagementConfigurationSelector给容器中注入两个组件:
* AutoProxyRegistrar,ProxyTransactionManagementConfiguration
* 1.AutoProxyRegistrar
* 给容器中注册一个InfrastructureAdvisorAutoProxyCreator组件
* 分析InfrastructureAdvisorAutoProxyCreator该类的作用
* 利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器)
*
* 2.ProxyTransactionManagementConfiguration
* 给容器中注册事务增强器
* 1.事务增强器要用事务注解信息,TransactionAttributeSource解析事务注解
* 2.事务拦截器:
* TransactionInterceptor;保存了事务属性信息,事务管理器
* 它是一个MethodInterceptor
* 在目标方法执行的时候:
* 执行拦截器链
* 事务拦截器:
* 1.获取事务属性
* 2.获取PlatormTransctionManager
-
- 代码
配置数据源和事务管理器:
@EnableTransactionManagement
@ComponentScan("com.chen.tx")
@Configuration
public class TxConfig {
@Bean
public DataSource dataSource() throws Exception{
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser("root");
dataSource.setPassword("root");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
return dataSource;
}
@Bean
public JdbcTemplate jdbcTemplate() throws Exception{
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
return jdbcTemplate;
}
//事务管理器
@Bean
public PlatformTransactionManager platformTransactionManager() throws Exception{
PlatformTransactionManager platformTransactionManager = new DataSourceTransactionManager(dataSource());
return platformTransactionManager;
}
}