第四节_spring注解开发学习

Spring注解开发

1、Spring原始注解

Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml文件以后可以简化配置,提高我们的开发效率

  • Spring原始注解主要是替代标签的配置
  • 主要的原始注解有
  • image-20220512112209058

2、完善我们的开发环境

2.1、先创建xml然后开始对比注解的方式

  • 创建dao层和Service还有web层的准备工作

  • package com.waves.dao;
    // dao层
    public interface UserDao {
        // 写了一个底层的save方法
        public void save();
    }
    
    // UserDao的实现类
    package com.waves.dao.impl;
    
    import com.waves.dao.UserDao;
    
    public class UserDaoImpl implements UserDao {
        @Override
        public void save() {
            System.out.println("save running.....");
        }
    }
    
    // Service层
    package com.waves.service;
    public interface UserService {
        // 调用底层的save方法
        public void save();
    
    }
    // 业务层的实现类
    public class UserServiceImpl implements UserService {
        // 将UserDao对象注入到UserService对象中--采用set的方法
        private UserDao userdao;
    
        // 初始化
        public void setUserdao(UserDao userdao) {
            this.userdao = userdao;
        }
    
        @Override
        public void save() {
            System.out.println("底层的save方法被调用......");
            userdao.save();
        }
    
    }
    
    // web层
    public class UserController {
        // 调用底层的save方法
        public static void main(String[] args) {
            // 加载配置文件
            ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
            // 获取UserService对象
            UserService service = app.getBean(UserService.class);
            service.save();
        }
    }
    
    
  • 运行结果image-20220321204556362

2.2、注解开发代替xml配置文件

image-20220321205245719

2.2.1、将需要注入到容器的组件进行注入

@Componet(id)–一定要写id,spring识别不出来

@Qualifier(“userDao”),你想要将哪个组件注入进来,就在里面写那个组件的id

@Autowried–自动注入


// 注解的方式帮我注入到容器中
@Component("userDao")
public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("save running.....");
    }
}
@Component("userService")
public class UserServiceImpl implements UserService {
    // 将UserDao对象注入到UserService对象中--采用set的方法
    @Autowired //自动注入
   	@Qualifier("userDao")    // 没懂
    private UserDao userdao;

    // 初始化
    public void setUserdao(UserDao userdao) {
        this.userdao = userdao;
    }

    @Override
    public void save() {
        System.out.println("底层的save方法被调用......");
        userdao.save();
    }

}

2.2.2、将UserDao对象注入到Service中

@Autowired //自动注入
@Qualifier("userDao")  // 没懂
private UserDao userdao;

2.2.3、配置扫描组件–xml中配置

<!-- 配置组件扫描,告诉Spring我那些包下的组件需要被扫描和注入 -->
<context:component-scan base-package="com.waves"></context:component-scan>

2.2.4、测试

image-20220321210737575

3、原始注解详解

原先注解的弊端,Componet注解无法明了,创建的组件,是哪个层的,语义不明确

3.1、@Repositpry,@Service,@Controller(现在用不上)

将原先dao层和service层的注解修改一下,明确语义

@Repository("userDao")
@Service("userService")

3.2、关于@Qualifier(名称注入)和@Autowired注解(类型注入)

  • @Qualifier会和Autowired相互配合,但是

  • 如果没有@Qualifier注解,@Autowired注解会从Spring的容器中进行匹配

  • 例如这个例子

  • @Autowired //自动注入
    // @Qualifier("userDao")  // 没懂
    private UserDao userdao;
    
  • 我取消了@Qualifier这个注解,那么@Autowired能不能给我注入呢?当然是可以的

  • 因为我为UserDao对象注入到了容器当中

  • 问题,如果容器当中存在多个UserDao的对象,那么这个时候@Autowired就不可以了,因为他不知道你到底需要将哪个UserDao对象依赖注入进来所以需要@Qualifier来指定对象的的id,他会根据id从容器中进行匹配,并且必须依赖于@Autowired注解

3.3、@Resource注解(= @Qualifier + @Autowired)

@Resource的name值就是组件的id值

@Resource(name="userDao")
private UserDao userdao;

3.4、value注解

3.4.1、可以注入普通值–鸡肋

  • 我在这里设置一个变量名,然后通过value注入一个很普通的值

  • 直接赋值就是普通的注入

// Value注入普通的值
@Value("instruct")
private String driver;
@Override
public void save() {
    System.out.println("我的driver值是:"+driver);
    System.out.println("底层的save方法被调用......");
    userdao.save();
}
  • 运行结果
  • image-20220321215245877

3.4.2、复杂类型的注入,properties–@Value(${})

  • 先把properties注入到xml配置文件中

  • <!-- 属性加载器 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    
  • //@Value("instruct")
    // 复杂类型的注入
    @Value("${jdbc.driver}")
    private String driver;
    @Override
    public void save() {
        System.out.println("我的driver值是:"+driver);
        System.out.println("底层的save方法被调用......");
        userdao.save();
    }
    
  • 测试

  • image-20220321215518375

  • 注入成功!

4、Spring新注解

使用新注解的原因,因为原始注解无法替代,第三方的bean,加载properties的配置文件context:property-placeholder,组件扫描context:componet-scan,引入其他配置文件import,这些都是我们原始注解无法进行替换的

image-20220321222326937

4.1、新注解学习流程

image-20220321222650927

4.2、@Configuration–配置类

该类是Spring的一个核心配置类用一个类的方式代替文件,注解的方式代替标签,他的目的就是为了替代xml配置文件

  • 创建我们的配置类

  • package com.waves.conifg;
    
    import org.springframework.context.annotation.Configuration;
    
    // 这个是我们的核心配置类--目的是为了替代核心配置文件application.xml
    @Configuration
    public class SpringDatasourceConfig {
    
    }
    

4.3、@ComponentScan–包扫描,容器对象创建需要扫描的包是谁?

  • 在配置类的基础上加上@ComponentScan

  • // 这个是我们的核心配置类--目的是为了替代核心配置文件application.xml
    @Configuration
    // <context:component-scan base-package="com.waves"></context:component-scan>
    @ComponentScan("com.waves")
    public class SpringDatasourceConfig {
    
    }
    

4.4、@Bean注解,解决第三方给我们创建的接口的调用–创建在方法上,方法的返回值对象会注入到容器当中

  • 在原有基础上加上@Bean注解

  • import javax.activation.DataSource;
    
    // 这个是我们的核心配置类--目的是为了替代核心配置文件application.xml
    @Configuration
    // <context:component-scan base-package="com.waves"></context:component-scan>
    @ComponentScan("com.waves")
    public class SpringDatasourceConfig {
    
        // 创建我们的第三方返回值对象
        @Bean("dataSource")
        public DataSource getDataSource() {
            
            return new DataSource();
        }
    }
    

4.5、@PropertySource注解,替换xml中导入properties的方法

导入值还是要从外面导入的,不能再方法内部导入,因为他会把SPL表达式当成字符串

  • 导入效果

  • // 这个是我们的核心配置类--目的是为了替代核心配置文件application.xml
    @Configuration
    // <context:component-scan base-package="com.waves"></context:component-scan>
    @ComponentScan("com.waves")
    @PropertySource("classpath:jdbc.properties")
    public class SpringDatasourceConfig {
        // 需要注入值的对象
        @Value("${jdbc.driver}")
        private String driver;
        @Value("${jdbc.url}")
        private String url;
        @Value("${jdbc.user}")
        private String user;
        @Value("${jdbc.password}")
        private String password;
    
        // 创建我们的第三方返回值对象
        @Bean("dataSource")
        public ComboPooledDataSource getDataSource() throws PropertyVetoException {
            // 对数据源数据进行注入
            ComboPooledDataSource dataSource = new ComboPooledDataSource();
            dataSource.setDriverClass(driver);
            dataSource.setJdbcUrl(url);
            dataSource.setUser(user);
            dataSource.setPassword(password);
            return dataSource;
        }
    }
    

4.6、@Import注解,该注解用于主配置文件导入副配置文件的作用

  • 我创建第二个配置类,这个类作为我们的主配置类

  • 导入Import,数据库配置类的注解

  • @PropertySource,这个注解谁需要谁才加入–建议

  • // 这个类是我们的主配置类
    @Configuration
    // 配置包扫描
    @ComponentScan("com.waves")
    // 导入我们的数据库配置类
    @Import(SpringDatasourceConfig.class)
    public class SpringConfigurataion {
        
    }
    

4.7、引入配置类–AnnotationConfigApplicationContext–舍弃了xml配置文件

  • 实战效果

  • 顺便查看我们的那个数据库对象是否成功引用到了

  • public class UserController {
        // 调用底层的save方法
        public static void main(String[] args) throws SQLException {
            // 加载配置文件
            //ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
            ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfigurataion.class);
            // 获取UserService对象
            UserService service = app.getBean(UserService.class);
            service.save();
            // 获取数据库的对象
            ComboPooledDataSource dataSource = (ComboPooledDataSource) app.getBean("dataSource");
            Connection connection = dataSource.getConnection();
            System.out.println(connection);
    
        }
    }
    
  • 实战效果

  • image-20220321232806860

  • very deep!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值