spring注解驱动开发

组件注册--@configuration

config配置类

//配置类==配置文件--(相当于bean.xml)
@Configuration //告诉spring这是一个配置类
public class MainConfig {


@Bean("person11") //给容器中注册一个bean,类型是 返回值的类型,id是 方法名作为id
public Person person(){
return new Person("李四","22");
}
}

测试

@Test
public void testconfig(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
Person bean = context.getBean(Person.class);
System.out.println(bean);
String[] namesForType = context.getBeanNamesForType(Person.class);
for (String name:namesForType) {
System.out.println(name);
}
}

注意

image-20230119161734628

image-20230119161623739

组件注册--@componentScan

excludeFilters()

image-20230119165953086

image-20230119165843766

includeFilters()

image-20230119170254622

compomentScans()

image-20230119170623239

image-20230119170636574

filtertype规则

image-20230119172112689

自定义过滤规则

image-20230119174631787

public class MyFilterType implements TypeFilter {
//metadataReader:读取当前正在扫描的类的信息
//metadataReaderFactory:读取其他类的任何信息

@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {

//获取当前正在扫描的 注解信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
//类资源(类的路径)
Resource resource = metadataReader.getResource();

//获取类的 名称
String className = classMetadata.getClassName();
System.out.println("---------->"+className);
if (className.contains("er")){
return true;
}
return false;
}
}

image-20230119174731210

image-20230119174808080

@scope

image-20230119205457715

singleton单实例

image-20230119204628777

结果

image-20230119204653302

ioc容器启动时 调用方法创建对象

image-20230119204844495

prototype多实例

image-20230119205330230

@lazy

image-20230119210024767

image-20230119210112363

@Conditional

image-20230119214324491

两个系统

image-20230119214406207

image-20230119214427964

结果

image-20230119214654111

linux

image-20230119215516941

image-20230119215604037

结果

image-20230119215633939

import–注册bean

image-20230119221011931

image-20230119221030394

image-20230119221105954

image-20230119221141714

importselector–注册bean

image-20230119222336639

image-20230119222234140

image-20230119222400052

image-20230119222414884

ImportBeanDefinitionRegistrar–注册bean

image-20230119224150262

image-20230119224215541

image-20230119224236016

FactoryBean

image-20230119231414057

实现factorybean

package com.miao.pojo;
import org.springframework.beans.factory.FactoryBean;
public class CatFactoryBean implements FactoryBean<Teacher> {
@Override
public Teacher getObject() throws Exception {
System.out.println("FactoryBean--CatFactoryBean--Teacher");
return new Teacher();
}

@Override
public Class<?> getObjectType() {
return Teacher.class;
}

//true: 单例,容器中bean只有一份
//false:多例,每次获取都会创建一个bean
@Override
public boolean isSingleton() {
return false;
}
}

image-20230119231631973

image-20230119231656770

bean

生命周期–bean的初始化

配置类

/**
* bean 的生命周期
* bean的创建--初始化--销毁的过程
* 容器管理bean的生命周期
* 可以自定义初始化和销毁方法,容器在bean进行当前的生命周期时候调用自定义的初始化和销毁方法
* 指定初始化和销毁方法
* 指定init-method和destroy-method
* 构造对象
* 单例:容器启动时创建对象
* 多例:获取的时候创建对象
* 销毁
* 单例:容器关闭的时候
* 多例:容器不会管理bean,容器不会调用销毁方法
*/
@Configuration
public class MainConfigLifeCycle {

@Bean(initMethod = "init",destroyMethod = "destroy")
public Car car(){
return new Car();
}
}

一个类

public class Car {
public Car(){
System.out.println("car--constructor----");
}
public void init(){
System.out.println("init ----------");
}
public void destroy(){
System.out.println("destroy---------");
}
}

结果

image-20230120083333777

多实例bean不会调用销毁方法

image-20230120083534790

image-20230120083502789

实现接口–初始化和销毁

image-20230120085234646

一个类

@Component
public class Dog implements InitializingBean, DisposableBean {
public Dog(){
System.out.println("dog--constructor---");
}

@Override
public void destroy() throws Exception {
System.out.println("dog--destroy--");
}

@Override
public void afterPropertiesSet() throws Exception {
System.out.println("dog--afterPropertiesSet--");
}
}

结果

image-20230120085155469

使用JSR250–初始化和销毁

image-20230120090339465

一个类

@Component
public class Food {
public Food() {
}
//对象创建并赋值后调用
@PostConstruct
public void init(){
System.out.println("food--PostConstruct");
}
@PreDestroy
public void destroy(){
System.out.println("food--PreDestroy");
}
}

小结

image-20230120090510267

beanpostprocessor–bean后置处理器

//bean后置处理器
@Component
public class MyPostBeanPorocessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization"+beanName+"---"+bean);
return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization"+beanName+"---"+bean);
return bean;
}
}

image-20230120091657580

image-20230120091747829

@value

image-20230120094704500

image-20230120094725748

@propertysource–读取配置文件值

image-20230120100435896

image-20230120100452787

image-20230120100509729

image-20230120100529847

applicationcontext读取属性值

image-20230120100649456

自动装配–autowired

  • 默认按照类型去容器中找对应的组件

  • 如果找到对个相同的组件,再将属性的名称作为组件的id去容器中找

    spring还支持:resource 和 inject注解

image-20230120104212677

profile–切换环境

/**
* profile;
* spring提供的 可以根据当前环境,动态的激活和切换一系列组件的功能
* 开发环境、测试环境、生产环境
* 数据源 :a b c
* @profile: 指定组件在哪一个环境被注册到容器中,不指定,都可以注册到容器中
* 加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中,默认是 default 环境
*
* 命令行传参: -Dspring.profiles.active=test
*
*/
@PropertySource("classpath:/dbconfig.properties")
@Configuration
public class MyconfigProfile implements EmbeddedValueResolverAware {

@Value("${db.user}")
private String user;
private StringValueResolver valueResolver;
private String driverClass;

@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/dev");
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/prod");
dataSource.setDriverClass(driverClass);
return dataSource;
}

@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
this.valueResolver = resolver;
driverClass = valueResolver.resolveStringValue("${db.driver}");
}
}

image-20230120132230546

image-20230120132041360

image-20230120132127071

第二种切换环境

image-20230120133720473

AOP

aop功能测试

目标类和切面类

public class MathCalculate {
public int calculate(int a,int b){
System.out.println("这是目标方法--calculate--");
return a/b;
}
}
###############################################
@Aspect //告诉spring容器这是一个 切面类
public class TargetAspects {

@Pointcut("execution(* com.miao.aop.MathCalculate.*(..))")
public void print(){}
@Before("print()")
public void targetStart(JoinPoint joinPoint){
System.out.println("返回的方法名:"+joinPoint.getSignature().getName()+"--@before--开始之前");
}
@After("print()")
public void targetEnd(JoinPoint joinPoint){
System.out.println("返回的方法名:"+joinPoint.getSignature().getName()+"--@after--运算结束");
}
@AfterReturning(value = "print()",returning = "result")
public void targetReturn(JoinPoint joinPoint,Object result){
System.out.println("返回的方法名:"+joinPoint.getSignature().getName()+"--@afterreturning--正常结束"+"返回值:"+result);
}
@AfterThrowing(value = "print()",throwing = "exception")
public void targetThrows(JoinPoint joinPoint,Exception exception){
System.out.println("返回的方法名:"+joinPoint.getSignature().getName()+"--@afterthrowing--出现异常了"+"出现的异常信息:"+exception);
}

}

配置类

/**
* AOP: 在程序运行期间动态的将某段代码切入到指定位置进行运行的编程方式
* 将业务逻辑组件和切面类都加入到容器中,并告诉spring哪个是切面类(添加@Aspect
* 在切面类上添加通知注解
* 开启基于注解的aop模式:@EnableAspectJAutoProxy
*/
@EnableAspectJAutoProxy //开启基于注解的aop模式
@Configuration
public class MyConfigAop {
@Bean
public MathCalculate mathCalculate(){
return new MathCalculate();
}
@Bean
public TargetAspects targetAspects(){
return new TargetAspects();
}
}

测试结果

image-20230120144649916

测试异常

image-20230120144732919

JdbcTemplate–操作事务

配置类

/**
* 声明式事务
* 相关依赖:数据源,数据库驱动,spring-jdbc
* 给方法上添加@Transactional 表示当前方法是一个 事务方法
* @EnableTransactionManagement 开启基于注解的事务管理功能
*
* 配置事务管理器控制事务 PlatformTransactionManager
*/
@EnableTransactionManagement
@ComponentScan("com.miao.tx")
@Configuration
public class TxConfig {

//数据源
@Bean
public DataSource dataSource() throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser("root");
dataSource.setPassword("123456");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/school");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
return dataSource;
}
@Bean
public JdbcTemplate jdbcTemplate() throws Exception {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource());
return jdbcTemplate;
}
//事务管理器
@Bean
public PlatformTransactionManager platformTransactionManager() throws Exception {
return new DataSourceTransactionManager(dataSource());
}
}

实体类

image-20230120173213763

image-20230120173252128

结果

image-20230120173404639