详细的描述了Spring中的注解开发。

注解开发定义Bean

步骤:

1.使用@Component定义Bean

以下两种方式都可以定义Bean

@Component(“Bean的名称”)

@Component

其中第一种方式可以使用 ctx.getBean(“名称”)

其中第二种方式只能使用 ctx.getBean(“类型.class”) 因为没有指定名称

2.核心配置文件中通过组件扫描加载Bean

<context:component-scan base-package="wang"/> <!-- 递归扫描 wang -->

注意:

Spring提供@Component注解的三个衍生注解

@controller:用于表现层bean定义
@service:用于业务层bean定义.
@Repository:用于数据层bean定义

样例代码:

impl实现类:

package wang.dao.impl;

import org.springframework.stereotype.Component;
import wang.dao.Dao;

@Component("dao")
public class DaoImpl implements Dao {
@Override
public void save() {
System.out.println("Dao save() ...");
}
}

xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">

<context:component-scan base-package="wang"/>

</beans>

主函数:

package wang;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import wang.dao.Dao;

public class App4 {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml.bak");
Dao dao = (Dao) ctx.getBean("dao");
dao.save();
}
}

运行结果:

SSM03-01注解开发定义Bean运行结果

纯注解开发模式

Spring3.0升级了纯注解开发模式,使用Java类替代配置文件,开启了Spring快速开发赛道

如何取消配置文件呢,使用一个配置类来代替配置文件

package wang.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("wang")
public class SpringConfig {

}

注意:

@ComponentScan(“wang”) 代替了中间的组件扫描器的功能

@Configuration代替了 xml 配置文件中的其他配置,如下图:

SSM03-02纯注解开发代替

注意:ComponentScan({“wang.xxx01”, “wang.xxx02”}) 可以扫描多个类

主函数中需要改变一行代码:

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

改为:

ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);

此时删除xml配置文件运行结果相同:

SSM03-03纯注解开发定义Bean运行结果

Bean的管理

Bean的作用范围

@Scope(“prototype”)即可更改

Bean的生命周期

如下代码:

实现类:

package wang.dao.impl;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import wang.dao.Dao;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Component
@Scope("singleton")
public class DaoImpl implements Dao {
@Override
public void save() {
System.out.println("Dao save() ...");
}

@PostConstruct
public void init() {
System.out.println("init() ... ");
}

@PreDestroy
public void destroy() {
System.out.println("destroy() ...");
}
}

主函数:

package wang;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import wang.config.SpringConfig;
import wang.dao.Dao;

public class AppForAnnotation {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
Dao dao1 = ctx.getBean(Dao.class);
Dao dao2 = ctx.getBean(Dao.class);
System.out.println(dao1);
System.out.println(dao2);
ctx.close();
}
}

注意关闭容器或关闭钩子可以看到销毁操作

运行结果如下:

SSM03-04bean的管理

注解开发依赖注入

@AutoWired —> 实现了引用类型的注入

注意:自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此无需提供setter方法

注意:自动装配建议使用无参构造方法创建对象(默认),如果不提供对应构造方法,请提供唯一的构造方法

样例代码如下:

package wang.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import wang.dao.Dao;
import wang.service.Service;

@Service
public class ServiceImpl implements Service {
@Autowired
@Qualifier("dao")
private Dao dao;

@Override
public void save() {
System.out.println("Service save() ...");
dao.save();
}
}

@Value(“变量值”) —> 实现了简单类型的注入

简单的样例代码如下:

@Service
public class ServiceImpl implements Service {
@Value("wang")
private string name;

@Override
public void save() {
System.out.println("Service save() ..." + name);
}
}

那么为什么不直接将name定义为“wang”呢?为什么还要多此一举呢?

因为可以通过@Value注入properties

在配置类中加入如下注解

@PropertySource({“xxx.properties”,“xxx.properties”}) 注意:不允许使用通配符

此时可以通过@Value(“${ 属性名 }”) 访问properties中的属性

注解开发管理第三方Bean

@Bean 表示当前方法的返回值是一个Bean

@Configuration
public class SpringConfig {
//1.定义一个方法获得要管理的对象
//2.添加@Bean,表示当前方法的返回值是一个bean
@Bean
public Datasource dataSource() {
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName("com.mysq1.jdbc.Driver");
ds.setUr1("jdbc:mysql://localhost:3306/spring_db");
ds.setUsername("root");
ds.setPassword("1234");
return ds;
}
}

写好当前配置文件后,在独立的配置类中导入当前配置类

方法1.扫描式 @ComponentScan({“xxx.service”, “xxx.dao”, “xxx.config”}) 不推荐

方法2.导入式 @Import(xxxconfig.class) 推荐,更为清晰

注入普通类型:

@Value("com.mysql.jdbc.Driver")
private string driver;
@value("jdbc:mysq1://localhost:3306/spring_db")
private string url;
@Value("root")
private string userName;
@Value("1234")
private string password;

使用@Value注入

注入引用类型

public Datasource dataSource() {
DruidDataSource ds = new DruidDataSource(Dao dao);
System.out.println(dao);
}

直接在形参声明即可,自动注入

XML配置对比注解配置

功能 XML配置 注解配置
定义Bean bean标签
• id属性
• class属性
@Component
• @Controller
• @Service
• @Repository<br>@ComponentScan
设置依赖注入 setter注入(set方法)
• 引用类型/简单类型
构造器注入(构造方法)
• 引用类型/简单类型
自动装配
@AutoWired
• @Qualifier<br>@Value
配置第三方Bean bean标签
静态工厂、实例工厂、FactoryBean
@Bean
作用范围 • scope属性 @Scope
生命周期 标椎接口
• init-method
• destroy-method
@PostConstructor<br>@PreDestroy