栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【Spring】IOC之Bean管理-注解方式(注解和XML的选择)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Spring】IOC之Bean管理-注解方式(注解和XML的选择)

注解: 是代码特殊标记,可以作用在类、方法、属性上,使用注解可以简化xml配置
格式:@注解名称(属性名称 =属性值, 属性名称 =属性值....)

使用注解方式管理Bean需要引入相关依赖

IOC之Bean管理-注解方式

一、用于创建对象的注解

1.1 快速入门1.2 `context:component-scan`标签

设置扫描的包设置扫描的内容设置不扫描的内容 二、用于注入属性的注解

2.1 使用`@Autowired`和`@Qualifier`注解2.2 使用`@Resource`注解2.3 使用`@Value`注解2.4 `@Scope`用于改变Bean作用范围的注解2.5 和Bean生命周期相关的注解 三、完全使用注解开发

3.1 使用`@Configuration`和`@ComponentScan`注解3.2 使用`@PropertySource`和`@Bean`注解3.3 使用`@import`注解配置类和配置文件可以写在类路径下的任意位置 四、注解和 XML 的选择

4.1 Spring 管理 Bean 方式的比较

一、用于创建对象的注解

相当于xml文件中的

注解描述
@Component作用: 把资源让 spring 来管理。相当于在 xml 中配置一个 bean。
属性:value:指定 bean 的 id。如果不指定 value 属性,默认 bean 的 id 是当前类首字母小写的类名
@Controller一般用于表现层的注解,作用与属性和@Component相同
@Service一般用于业务层的注解,作用与属性和@Component相同
@Repository一般用于持久层的注解,作用与属性和@Component相同

上面四个注解功能是一样的,都可以用来创建bean的实例
如果注解中有且只有一个属性要赋值时,且名称是 value,则 value 在赋值是可以不写。

1.1 快速入门

使用注解需要先开启组件扫描,需要用到spring中xmlns:context的约束



    
    

开启组件扫描后,创建类,并且在类上添加创建对象的注解

@Component(value = "userService")
public class UserService {
    public void add() {
        System.out.println("service add....");
    }
}

这里的@Component(value = "userService")相当于xml形式的


而value属性可以省略不写,不写的话默认设置id为首字母小写的当前类名,比如UserService则默认为userService。

@Component也可以变更为其他三个注解,因为效果是一样的,四种不同的注解可以做区分效果,比如Service层的类可以使用@Service注解,Dao层的类可已使用@Repository注解

@Test
public void testService() {
    ApplicationContext context = new ClassPathXmlApplicationContext("bean4_1.xml");
    UserService userService = context.getBean("userService", UserService.class);
    userService.add();
}

通过上面的测试方法可以得到以下结果,说明注解方式使用成功

1.2 context:component-scan标签 设置扫描的包

开启组件扫描设置扫描的包有两种方法:

    如果需要扫描多个包,可以使用逗号隔开

这里扫描的就是run.arbor.spring5demo4中的dao包和service包


    需要扫描包的上层目录

这里扫描的就是run.arbor.spring5demo4中的类和所有子包中的类


设置扫描的内容

如果想扫描run.arbor.spring5demo4包中所有带@Controller的类,不想扫描带@Service或者其他两个注解的类,可以使用filter来完成相关功能

use-default-filters="false":不使用默认的filter,自定义filter:设置扫描哪些内容

type="annotation":扫描注解expression="org.springframework.stereotype.Controller":扫描使用Controller注解的类


	

设置不扫描的内容

如果想扫描run.arbor.spring5demo4包中所有除了带@Controller的类,可以使用标签

:设置不扫描哪些内容

type="annotation":扫描注解expression="org.springframework.stereotype.Controller":不扫描使用Controller注解的类


	

二、用于注入属性的注解

相当于xml文件的:

注解描述
@Autowired自动按照类型注入。 只能注入其他 bean 类型,set 方法可以省略。当有多个类型匹配时,需要使用@Qualifier注解来指定 bean 的 id。
@Qualifier作用: 在自动按照类型注入的基础之上,再按照 Bean 的 id 注入。它在给字段注入时不能独立使用,必须和 @Autowired 一起使用;但是给方法参数注入时,可以独立使用。
属性: value:指定 bean 的 id。
@Resource作用: 直接按照 Bean 的 id 注入。它也只能注入其他 bean 类型。
属性: name:指定 bean 的 id。
@Value作用: 注入基本数据类型和 String 类型数据的属性
属性: value:用于指定值
2.1 使用@Autowired和@Qualifier注解

创建dao对象

// value可以自定义对象的名字
@Repository(value = "userDaoImpl")
public class UserDaoImpl implements UserDao{
    @Override
    public void add() {
        System.out.println("dao add...");
    }
}

如果UserDao有多个实现类的话,必须使用@Qualifier来确定注入的是哪个对象,如果只有一个实现类那么写不写 @Qualifier 都可以,如果写的话,value属性必须和UserDao对象创建时的value值相同,比如:@Repository(value = “userDaoImpl111”),那么就必须是 @Qualifier(value = “userDaoImpl111”)

@Component(value = "userService")
public class UserService {

    // 使用@Autowired注解,定义UserDao类型的属性,可以不用set方法
    @Autowired
    @Qualifier(value = "userDaoImpl")  // 根据名称注入
    private UserDao userDao;

    public void add() {
        System.out.println("service add...");
        userDao.add();
    }
}
2.2 使用@Resource注解

因为@Resource注解是Java的拓展包,不是Spring官方提供的,所以更建议使用上面两个注解

如果UserDao有多个实现类的话,必须使用name属性值来确定注入的是哪个对象,如果只有一个实现类那么写不写name都可以

@Component(value = "userService")
public class UserService {

//    @Resource   // 根据类型注入
    @Resource(name = "userDaoImpl1")    // 根据名称注入
    private UserDao userDao;

    public void add() {
        System.out.println("service add...");
        userDao.add();
    }
}
2.3 使用@Value注解

注入基本数据类型和 String 类型数据的属性

@Component(value = "userService")
public class UserService {

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

    @Value(value = "abc")   // 基本类型注入和String类型注入
    private String name;

    public void add() {
        System.out.println("service add...");
        System.out.println(name);
        userDao.add();
    }
}

也可以通过spring的表达式获取配置文件中的值,可以看本文的 3.2 小节的第二步代码演示

2.4 @Scope用于改变Bean作用范围的注解

相当于:的scope=""
作用: 指定 bean 的作用范围。
属性: value:指定范围的值。
value取值:

描述
singleton默认值,单例的
prototype多例的
requestWEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中
sessionWEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中
globalsessionWEB 项目中,应用在 Portlet 环境。如果没有 Portlet 环境那么globalSession 相当于 session
2.5 和Bean生命周期相关的注解

相当于:的init-method="" destroy-method=""

注解描述
@PostConstruct用于指定初始化方法
@PreDestroy用于指定销毁方法
三、完全使用注解开发

在上面的代码中,使用注解需要先在xml文件中开启组件扫描,这样还是需要配置文件,这一步也可以使用注解配置

注解描述
@Configuration作用: 指定当前类是一个 spring 配置类,当创建容器时会从该类上加载注解。
获取容器时需要使用AnnotationConfigApplicationContext(有@Configuration 注解的类.class)。
属性: value:用于指定配置类的字节码
@ComponentScan作用: 用于指定 spring 在初始化容器时要扫描的包。作用和xml配置文件中的: 是一样的。
属性:
- basePackages:用于指定要扫描的包。
- value:和basePackages的属性作用一样
@Bean作用: 该注解只能写在方法上,表明使用此方法创建一个对象,并且放入 spring 容器。
属性: name:给当前@Bean注解方法创建的对象指定一个名称(即 bean 的 id)。
@PropertySource作用: 用于加载 .properties文件中的配置。例如配置数据源时,可以把连接数据库的信息写到 properties 配置文件中,就可以使用此注解指定 properties 配置文件的位置。
属性: value[]:用于指定 properties 文件位置。如果是在类路径下,需要写上classpath:
@import作用: 用于导入其他配置类,在引入其他配置类时,可以不用再写@Configuration 注解,写上也没问题。
属性: value[]:用于指定其他配置类的字节码。
3.1 使用@Configuration和@ComponentScan注解

第一步: 创建配置类,用于替代xml配置文件,类名随意
工作中一般会创建一个config包用于放配置类

@Configuration  // 告诉spring这是一个配置类
@ComponentScan(basePackages = {"run.arbor"})  // 用于指定 spring 在初始化容器时要扫描的包。
// 相当于xml文件的:
public class SpringConfig {
}

第二步: 此时再使用Spring创建的对象的时候,需要使用AnnotationConfigApplicationContext来获取,而参数中应该传入刚刚写的添加了@Configuration和@ComponentScan注解的类

@Test
public void testService() {
	// 使用AnnotationConfigApplicationContext
    ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
    UserService userService = context.getBean("userService", UserService.class);
    userService.add();
}
3.2 使用@PropertySource和@Bean注解

第一步: 比如我们要配置一个数据源,可以在src目录下写一个jdbc.properties文件:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/day44_ee247_spring
jdbc.username=root
jdbc.password=1234

第二步: 创建一个配置类

@Configuration
@PropertySource("classpath:jdbc.properties")	// 因为在src目录下,可以使用classpath:写相对路径
public class JdbcConfig{
    
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;
    
    
	@Bean(name="dataSource")
	public DataSource createDataSource() {
		try {
			ComboPooledDataSource ds = new ComboPooledDataSource();
			ds.setDriverClass(driver);
            ds.setJdbcUrl(url);
            ds.setUser(username);
            ds.setPassword(password);
			return ds;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
    }
    
	
	@Bean(name="dbAssit")
	public DBAssit createDBAssit(DataSource dataSource) {
		return new DBAssit(dataSource);
	}
}
3.3 使用@import注解

在上一小节 3.2 的基础上,使用@import注解将刚刚创建的配置类引入

@Configuration
@ComponentScan(basePackages = "run.arbor.spring")
@import({JdbcConfig.class})	// 将刚刚创建的配置类引入
public class SpringConfiguration {
}

此时可以在测试方法中,通过SpringConfiguration类(↑这个类)来创建对象。

ApplicationContext ac = 
new AnnotationConfigApplicationContext(SpringConfiguration.class);
配置类和配置文件可以写在类路径下的任意位置

.

四、注解和 XML 的选择

注解的优势:
配置简单,维护方便(找到类,就相当于找到了对应的配置)。
XML 的优势:
修改时,不用改源码。不涉及重新编译和部署。

基于注解的 Spring IOC 配置中,bean 对象的特点和基于 XML 配置是一模一样的。

4.1 Spring 管理 Bean 方式的比较
基于XML配置基于注解配置
Bean定义@Component
衍生类 @Repository、@Service、@Controller
Bean名称通过id或name执行@Component("这里指定")
Bean注入或者p命名空间@Autowired 按类型注入
@Qualifier按名称注入
生命过程、Bean作用范围init-method、destroy-method;范围scope属性@PostConstruct初始化
@PreDestroy销毁
@Scope设置作用范围
适用场景Bean来自第三方Bean的实现类由自己开发(工作中常用)
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/703238.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号