Spring-注解开发

Spring学习笔记目录
使用配置数据源的项目继续练习

Spring注解开发

注解说明
@Configuration使用在类上用于实例化Bean
@Controller使用在web层类上用于实例化Bean
@Service使用在service层类上用于实例化Bean
@Repository使用在dao层类上用于实例化Bean
@Autowired使用在字段上用于根据类型依赖注入
@Qualifier结合@Autowired一起使用用于根据名称进行依赖注入
@Resource相当于@Autowired+@Qualifier,按照名称进行注入
@Value注入普通属性
@Scope标注Bean的作用范围
@PostConstruct使用在方法上标注该方法是Bean的初始化方法
@PreDestroy使用在方法上标注该方法是Bean的销毁方法

在这里插入图片描述

XML配置方式(回顾)

回顾XML配置方式然后与注解开发进行比较,易于理解
项目结构:
在这里插入图片描述
新建接口UserDao.java:

package com.stu.dao;

/**
 * @version:
 * @author: 零乘一
 * @description:
 * @date: 2021/9/27 16:35
 **/
public interface UserDao {
    public void save();
}

新建实现类UserDaoImpl.java:

package com.stu.dao.impl;

import com.stu.dao.UserDao;

/**
 * @version:
 * @author: 零乘一
 * @description:
 * @date: 2021/9/27 16:37
 **/
public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("save runing....");
    }
}

新建接口UserService.java:

package com.stu.service.dao;

/**
 * @version:
 * @author: 零乘亿
 * @description:
 * @date: 2021/9/27 16:39
 **/
public interface UserService {
    public void save();
}

新建实现类UserServiceImpl.java:

package com.stu.service.dao.impl;

import com.stu.dao.UserDao;
import com.stu.service.dao.UserService;

/**
 * @version:
 * @author: 零乘亿
 * @description:
 * @date: 2021/9/27 16:39
 **/
public class UserServiceImpl implements UserService {
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public void save() {
        userDao.save();
    }
}

新建UserController.java:用于测试

package com.stu.web;

import com.stu.service.dao.UserService;
import com.stu.service.dao.impl.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @version:
 * @author: 零乘亿
 * @description:
 * @date: 2021/9/27 16:51
 **/
public class UserController {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = applicationContext.getBean(UserServiceImpl.class);
        userService.save();
    }
}

applicationContext.xml新增以下配置:

	<bean id="userDao" class="com.stu.dao.impl.UserDaoImpl"/>
    <bean id="userService" class="com.stu.service.dao.impl.UserServiceImpl">
        <property name="userDao" ref="userDao"/>
    </bean>

运行结果

运行UserController类文件
在这里插入图片描述
测试类中的save方法被成功执行,说明配置成功。

注解开发示例

查看applicationContext.xml文件中的配置
在这里插入图片描述
在使用注解代码开发时,会将以上的bean以注解的方式在代码中进行配置。
UserDaoImpl.java新增以下配置:

//<bean id="userDao" class="com.stu.dao.impl.UserDaoImpl"/>
@Component("userDao")

在这里插入图片描述

//<bean id="userService" class="com.stu.service.dao.impl.UserServiceImpl" />
@Component("userService")
    //<property name="userDao" ref="userDao"></property>
    @Autowired
    @Qualifier("userDao")

在这里插入图片描述
做完以上配置后,运行UserController.java文件后发现控制台报错如下:
在这里插入图片描述
这是因为我们虽然在代码中配置了注解,但是在xml中并没有告诉spring我们配置了这些注解,所以要在xml配置组件扫描代码。
applicationContext.xml文件中新增以下代码块:

<!--组件扫描-->
    <context:component-scan base-package="com.stu"/>

运行UserController.java文件

运行结果

在这里插入图片描述
成功打印出结果,说明注解配置成功。

分层注解

在上面的部分我们能够看到有很多的注解都可以用于bean的实例化,但是在上一个例子中只使用了@Component注解,其它的注解是为了更强的语义化。
在UserDaolImpl.java新增以下代码:

@Repository("userDao")

在这里插入图片描述
Dao层一般是用于数据持久层的,使用@Repository注解进行标注,这样语义化更好,在开发之后看代码时就能够很好的表示这一层是Dao。
UserServiceImpl.java新增以下代码:

@Service("userService")

在这里插入图片描述
这一层是Service所以将注解改成了@Service
运行UserController.java

运行结果

在这里插入图片描述
运行结果有打印结果,说明注解配置成功。

属性注入注解方式

①按照类型注入

    @Autowired

②使用id的注入方式

    @Autowired
    @Qualifier("userDao")

使用②时要注意,在配置当中,相同类型的bean在Spring容器中只能存在一个,若存在多个则会不知道应该要注入哪个bean从而出错。
③相当于@Autowired+@Qualifier()的注入方式

	@Resource(name="userDao")

jdk9以上不支持该操作,需要手动导入坐标。
注意:在使用注解进行属性注入时,在对象的内部不需要写对该属性的set方法,但是使用XML进行配置时就一定要协商。
在UserServiceImpl.java文件中的属性注入的注解中进行修改即可,修改之后在运行UserController查看打印结果。即可知道属性注入是否有成功。
在这里插入图片描述

普通属性注入

将UserServiceImpl.java定义的代码块进行替换:

public class UserServiceImpl implements UserService {
    //<property name="userDao" ref="userDao"></property>
//    @Autowired
//    @Qualifier("userDao")
    @Resource(name="userDao")
    private UserDao userDao;

    @Value("张三")
    private String name;

    @Override
    public void save() {
        System.out.println(name);
        userDao.save();
    }
}

在这里插入图片描述

运行结果

运行UserController.java文件:
在这里插入图片描述
成功打印出name说明配置成功,但这并不是注解value的主要用法。

普通属性注入使用EL表达式

将UserServiceImpl.java类重点的普通属性注入改为以下代码:

@Value("${jdbc.Driver}")

在这里插入图片描述

运行结果

运行UserController.java文件:
在这里插入图片描述
这才是注解Value的正确使用方法✔

代码解析

在这里插入图片描述
注解中的参数是一个EL表达式,表达式中的值是配置文件中的键值对中的其中一个key。
在这里插入图片描述
因为在xml中已经导入了properties文件中的键值对,所以在Spring空间中已经存在了这些键值对,所以在注解中写入EL表达式能够将通过key-value对的方式,通过key将value赋值给变量name。

新增初始化方法与销毁方法

UserController.java替换main方法

    public static void main(String[] args) {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = applicationContext.getBean(UserServiceImpl.class);
        userService.save();
        applicationContext.close();
    }

在这里插入图片描述
如果不执行close方法就无法看见destroy()方法的执行结果,因为在执行方法前,对象已经关闭。
UserServiceImpl.java新增以下代码:

    //初始化执行
    @PostConstruct
    public void init(){
        System.out.println("init....");
    }
    
    //对象销毁时执行
    @PreDestroy
    public void destroy(){
        System.out.println("destroy....");
    }

运行结果

在这里插入图片描述

Spring新注解

原始注解对于一些xml中的标签无法实现,所以需要引入新注解。

注解说明
@Configuration用于指定当前类是一个 Spring 配置类,当创建容器时会从该类上加载注解
@ComponentScan用于指定 Spring 在初始化容器时要扫描的包。
@Bean使用在方法上,标注将该方法的返回值存储到 Spring 容器中
@PropertySource用于加载.properties 文件中的配置
@Import用于导入其他配置类

在这里插入图片描述

新注解示例

目录结构:
在这里插入图片描述
新建SpringConfiguration.java:

package com.stu.config;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;

import javax.sql.DataSource;
import java.beans.PropertyVetoException;

/**
 * @version:
 * @author: 零乘一
 * @description: Spring核心配置文件
 * @date: 2021/9/28 15:30
 **/
//标志该类是Spring的核心配置类
@Configuration
//<context:component-scan base-package="com.stu"/>
@ComponentScan("com.stu")
//<import resource="">
@Import({DataSourceConfiguration.class})
public class SpringConfiguration {

}

新建DataSourceConfiguration.java:

package com.stu.config;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;

import javax.sql.DataSource;
import java.beans.PropertyVetoException;

/**
 * @version:
 * @author: 零乘一
 * @description: 数据源相关配置
 * @date: 2021/9/28 15:44
 **/
//<context:property-placeholder location="classpath:jdbc.properties" />
//<context:property-placeholder location="classpath:jdbc.properties" />
@PropertySource("classpath:jdbc.properties")//将properties中的数据载入Spring配置中
public class DataSourceConfiguration {
    @Value("${jdbc.Driver}")
    private String driver;

    @Value("${jdbc.url}")
    private String url;

    @Value("${jdbc.username}")
    private String user;

    @Value("${jdbc.password}")
    private String password;

    @Bean("dataSource") //Spring会将当前方法的返回值以指定名称存储到Spring容器中
    public DataSource getDataSource() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(driver);
        dataSource.setJdbcUrl(url);
        dataSource.setUser(driver);
        dataSource.setPassword(driver);
        return dataSource;
    }
}

UserController.java新增以下代码:

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfiguration.class);

在这里插入图片描述

运行结果

在这里插入图片描述
成功打印,说明新注解配置成功。

可能遇见bug

①Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder ‘jdbc.driver’ in value “${jdbc.driver}”
以上bug说明jdbc.driver这个表示是无法被识别的,因此很有可能是配置文件中的k-v对值写错。获取的这方与文件中的key无法对应上。

新注解详解


在这里插入图片描述

在这里插入图片描述
在@Import({…})这个注解中,内容是一组数组,需要引入多个配置类时,在第一个配置类后再加上一个逗号",",然后再写上下一个配置类即可引入。


在这里插入图片描述
这样的路径引入的配置文件,文件需要放在resources文件夹才能够找到。


在这里插入图片描述
⑤AnnotationConfigApplicationContext类
在这里插入图片描述
这个类就是我们之前提到的加载类配置文件对于的Application实现类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值