SSM框架学习——Spring之注解开发

目录

一、注解开发定义bean

二、衍生注解

三、纯注解开发

3.1配置文件基础

3.2Bean管理

3.2.1单例控制演示

3.2.2生命周期控制演示

3.2.3Bean管理总结

3.3依赖注入

3.3.1使用@Autowired注解开启自动装配模式(按类型)

3.3.2使用@Qualifier注解开启指定名称装配bean(依赖@Autowired)

3.3.3使用@Value实现简单类型注入 

3.3.4使用@PropertySource注解加载properties文件

3.4第三方bean管理

3.4.1使用@Bean配置第三方bean

3.4.2使用独立的配置类管理第三方bean

3.4.3实现为第三方bean注入资源

总结


一、注解开发定义bean

①使用@Component定义bean

@Component("Service3")
public class ServiceImpl3 implements Service3 {
    @Override
    public void show() {
        System.out.println("service3...");
    }
}

@Component
public class ServiceImpl4 implements Service4 {
    @Override
    public void show() {
        System.out.println("service4...");
    }
}

②核心配置文件中通过组件扫描加载bean

<context:component-scan base-package="Service.impl"/>

注意:如果@Component后面没有定义bean的id需要用类型来获取。

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Service3 service3 = (Service3) context.getBean("Service3");
service3.show();
Service4 service4 = context.getBean(Service4.class);
service4.show();

二、衍生注解

Spring提供@component注解的三个衍生注解:
@Controller :用于表现层bean定义
@Service : 用于业务层bean定义

@Repository :用于数据层bean定义

作用:只是为了区别不同层用的

三、纯注解开发

3.1配置文件基础

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

那么如何用Java类代替Spring核心配置文件?

@Configuration  //这个注解相当于原来配置文件中<?xml ?> <beans> </beans>这两个标签什么都不加。
@ComponentScan({"Service.impl","Dao.impl"}) //这个注解相当于<beans> </beans>中的<context:component-scan/>
public class SpringConfig {
}

如何运行?

读取Spring核心配置文件初始化容器对象切换为读取Java配置类初始化容器对象。
 

//加载配置文件初始化容器
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//加载配置类初始化容器
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);

新的实现类AnnotationConfigApplicationContext。

public class AppForAnnotation {
    public static void main(String[] args) {
        ApplicationContext context =new AnnotationConfigApplicationContext(SpringConfig.class);
        Service3 service3 = (Service3) context.getBean("Service3");
        service3.show();
        Service4 service4 = context.getBean(Service4.class);
        service4.show();
        Dao4 dao4 = context.getBean(Dao4.class);
        dao4.show();
    }
}

注意:

@Configuration注解用于设定当前类为配置类.。
@ComponentScan注解用于设定扫描路径,此注解只能添加一次,多个数据请用数组格式。

3.2Bean管理

3.2.1单例控制演示

①编代码

@Repository
public class DaoImpl4 implements Dao4 {
    @Override
    public void show() {
        System.out.println("dao..");

    }
}
public class App10 {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        Dao4 dao1 =context.getBean(Dao4.class);
        Dao4 dao2 =context.getBean(Dao4.class);
        System.out.println(dao1);
        System.out.println(dao2);
    }
}

②输出结果,可见是单例

 ③在DaoImpl4中新增注释@Scope("prototype")

@Repository
@Scope("prototype")
public class DaoImpl4 implements Dao4 {
    @Override
    public void show() {
        System.out.println("dao..");

    }
}

④再次运行输出结果,不一样有木有!

3.2.2生命周期控制演示

①导入maven依赖坐标

<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
</dependency>

②添加注解

@Repository
@Scope("singleton")
public class DaoImpl4 implements Dao4 {
    public void show() {
        System.out.println("dao..");
    }
    @PostConstruct //构造方法之后
    public void init() {
        System.out.println("init..");
    }
    @PreDestroy  //销毁之前
    public void destroy() {
        System.out.println("destroy..");
    }
}

③先不改上面的运行代码,运行发现没有执行销毁前方法

④如何修改?

public class App10 {
    public static void main(String[] args) {
        //ApplicationContext没有close方法,改为AnnotationConfigApplicationContext 
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        Dao4 dao1 =context.getBean(Dao4.class);
        Dao4 dao2 =context.getBean(Dao4.class);
        System.out.println(dao1);
        System.out.println(dao2);
        context.close();
    }
}

⑤再运行,成功执行destroy方法

3.2.3Bean管理总结

使用@Scope定义bean作用范围

@Scope("singleton")//单例
@Scope("prototype")//非单例

使用@Postconstruct、 @PreDestroy定义bean生命周期

@Postconstruct //构造之后执行
@PreDestroy  //销毁前执行

3.3依赖注入

3.3.1使用@Autowired注解开启自动装配模式(按类型)

@Service
public class ServiceImpl4 implements Service4 {
    @Autowired
    private Dao4 dao4;
    //@Autowired
    public void setDao4(Dao4 dao4) {
        this.dao4 = dao4;
    }

    @Override
    public void show() {
        System.out.println("service4...");
        dao4.show();
    }
}

@Autowired放在哪里都没有问题,

@Service
public class ServiceImpl4 implements Service4 {
    @Autowired
    private Dao4 dao4;
    @Override
    public void show() {
        System.out.println("service4...");
        dao4.show();
    }
}

注意︰自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此无需提供setter方法注意∶自动装配建议使用无参构造方法创建对象(默认),如果不提供对应构造方法﹐请提供唯一的构造方法。

3.3.2使用@Qualifier注解开启指定名称装配bean(依赖@Autowired)

@Repository("dao4") //指定id
@Scope("singleton")
public class DaoImpl4 implements Dao4 {
    public void show() {
        System.out.println("dao4..");
    }
    @PostConstruct //构造方法之后
    public void init() {
        System.out.println("init..");
    }
    @PreDestroy  //销毁之前
    public void destroy() {
        System.out.println("destroy..");
    }
}
@Repository("dao41") //指定id
public class DaoImpl5 implements Dao4 {
    @Override
    public void show() {
        System.out.println("dao41..");
    }
}
@Service
public class ServiceImpl4 implements Service4 {
    @Autowired
    @Qualifier("dao41") //指定注入id为dao41的bean
    private Dao4 dao4;

    @Override
    public void show() {
        System.out.println("service4...");
        dao4.show();
    }
}
public class App11 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        Service4 service4 =context.getBean(Service4.class);
        service4.show();
    }
}

运行结果:

 从结果可以看出,指定注入的是dao41,但是dao4的init方法也被执行。

注意:@Qualifier注解无法单独使用,必须配合@Autowired注解使用

3.3.3使用@Value实现简单类型注入 

@Repository("dao41")
public class DaoImpl5 implements Dao4 {
    @Value("ylm")
    private String name;
    @Override
    public void show() {
        System.out.println("dao41.."+name);
    }
}

运行结果:

3.3.4使用@PropertySource注解加载properties文件

@Repository("dao41")
public class DaoImpl5 implements Dao4 {
    @Value("ylm")
    private String name;
    @Value("${jdbc.password}")
    private String password;

    @Override
    public void show() {
        System.out.println("dao41.." + name + password);
    }
}
@Configuration
@ComponentScan({"Service.impl","Dao.impl"})
@PropertySource("jdbc.properties") //加载配置文件,多个配置文件依旧使用数组,但是不支持使用通配符
//@PropertySource({"jdbc.properties","jdbc2.properties"})
//@PropertySource({"classpath:jdbc.properties","classpath:jdbc2.properties"})
//通配符是会报错的*.properties , classpath*:这两种都会报错。
public class SpringConfig {
}
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/brand
jdbc.user=root
jdbc.password=123456

运行结果:

 注意∶路径仅支持单一文件配置,多文件请使用数组格式配置,不允许使用通配符*

3.4第三方bean管理

3.4.1使用@Bean配置第三方bean

配置类

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

运行代码

public class App12 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        DataSource dataSource = context.getBean(DataSource.class);
        System.out.println(dataSource);
    }
}

运行结果

这样写有个问题,就是如果都这样写SpringConfig主配置类得写多少?接着看下面。

3.4.2使用独立的配置类管理第三方bean

方式一:扫描式

这样改进,拆成专用配置类,放在包Config下,在主配置类SpringConfig里使用@ComponentScan注解扫描配置类所在的包,加载对应的配置类信息,都添加@Configuration。

SpringConfig

@Configuration
@ComponentScan({"Config"})
public class SpringConfig {
}

ThirdPartySpringConfig

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

再次运行App12:

(其实我在测试ComponentScan时,不加ComponentScan,也不写@Configuration,依然能用,只要有个@Bean就可以,不知道为何,可能是为了更好的理解这样的思维方式)。

 这样还是不推荐,推荐使用的导入式,就是下面的方法。

方式二:导入式

推荐使用@Import,手动加入配置类到核心配置,此注解只能添加一次,多个数据请用数组格式

SpringConfig

@Configuration
@Import({ThirdPartySpringConfig.class})
public class SpringConfig {
}

ThirdPartySpringConfig

//不用再写@Configuration
public class ThirdPartySpringConfig {
    //1.定义一个方法获得要管理的对象
    //2.添加@Bean,表示当前方法返回的是一个bean
    @Bean
    public DataSource dataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        druidDataSource.setUrl("jdbc:mysql://localhost:3306/brand");
        druidDataSource.setUsername("root");
        druidDataSource.setPassword("123456");
        return  druidDataSource;
    }
}

运行结果:

3.4.3实现为第三方bean注入资源

依赖注入类型:

简单类型注入(使用@Value),用成员变量。

引用类型注入, 用方法形参。引用类型注入只需要为bean定义方法设置形参即可,容器会根据类型自动装配对象

ThirdPartySpringConfig 

public class ThirdPartySpringConfig {
    //1.定义一个方法获得要管理的对象
    //2.添加@Bean,表示当前方法返回的是一个bean

    //简单类型
    @Value("com.mysql.jdbc.Driver")
    private String driver;
    @Value("jdbc:mysql://localhost:3306/brand")
    private String url;
    @Value("root")
    private String userName;
    @Value("123456")
    private String password;

    @Bean
    public DataSource dataSource(NewDao newDao){ //引用类型,NewDao按照类型自动装配
        System.out.println(newDao);
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(driver);
        druidDataSource.setUrl(url);
        druidDataSource.setUsername(userName);
        druidDataSource.setPassword(password);
        return  druidDataSource;
    }
}

NewDao

@Repository
public class NewDaoImpl implements NewDao {
    @Override
    public void show() {
        System.out.println("NewDao");
    }
}

运行代码

public class App13 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        DataSource dataSource = context.getBean(DataSource.class);
        System.out.println(dataSource);
    }
}

运行结果:

总结

XML配置与注解配置比较:

功能XML配置注解
定义bean

bean标签

   ·id属性

   ·class属性

@Component

   ·@Controller

   ·@service

   ·@Repository

@ComponentScan

设置依赖注入

setter注入( set方法)
   ·引用类型/简单类型

构造器注入(构造方法)
   ·引用类型/简单类型

自动装配

@Autowired

   ·@Qualifier

@Value

配置第三方bean

bean标签

静态工厂、实例工厂、FactoryBean

@Bean
作用范围scope属性@Scope
生命周期标准接口
   ·init-method
   ·destroy-method

@PostConstructor

@PreDestroy

标红表示常用,可以重点学习复习。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员Lyle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值