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

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

【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、@ControllerBean名称通过id或name执行@Component("这里指定")Bean注入或者p命名空间@Autowired 按类型注入
@Qualifier按名称注入生命过程、Bean作用范围init-method、destroy-method;范围scope属性@PostConstruct初始化
@PreDestroy销毁
@Scope设置作用范围适用场景Bean来自第三方Bean的实现类由自己开发(工作中常用)

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5703344.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存