当前位置:首页 >> 跨学科知识体系 >> 【Spring总结】注解开发,华为g606怎么样

【Spring总结】注解开发,华为g606怎么样

cpugpu芯片开发光刻机 跨学科知识体系 1
文件名:【Spring总结】注解开发,华为g606怎么样 【Spring总结】注解开发

本篇讲的内容主要是基于Spring v2.5的注解来完成bean的定义 之前都是使用纯配置的方式来定义的bean

文章目录 前言1. Spring v2.5 注解开发定义bean第一步:在需要定义的类上写上注解`@Component`第二步:在Spring Config中定义扫描包第三步:主方法中测试基于@Component的衍生注解 2. Spring v3.0 纯注解开发第一步:创建配置类第二步:导入配置类 3. Bean的作用范围(单例/多例)与生命周期Bean的作用范围Bean的生命周期 4.依赖注入引用类型注入@Autowire属性默认按类型注入按类型注入反射结果不唯一,按名注入按名注入的标准写法(少用) 简单类型注入引入外部的properties文件 5. 第三方Bean管理依赖注入简单类型注入引用类型注入 6. XML配置比对注解配置

前言

XML配置解耦,而注解是简化开发

1. Spring v2.5 注解开发定义bean

之前都是使用纯配置的方式,在Spring Config中通过<bean id="xxx" class="xxx" />来定义的bean,从此处开始将根据注解开发定义bean

第一步:在需要定义的类上写上注解@Component

这里有两种写的形式: @Component 或者是给其定义名称 @Component("bookDao") 通过第一种形式,就通过在getBean()方法中写类型来获得bean 通过第二种形式,就通过在getBean()方法中写名称来获得bean

package com.example.demo.dao.impl;import com.example.demo.dao.BookDao;import org.springframework.stereotype.Component;@Component// @Component("bookDao")public class BookDaoImpl implements BookDao {@Overridepublic void save() {System.out.println("Book Dao Save...");}} 第二步:在Spring Config中定义扫描包

注意,这里也要开启命名空间 然后通过<context:component-scan base-package="...." />进行定义扫描的包,这里就是扫描com.example.demo.dao下边的包,修改这个包为com.example.demo也是可以的

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="com.example.demo.dao" /></beans> 第三步:主方法中测试 package com.example.demo;import com.example.demo.dao.BookDao;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class DemoApplication {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");// 第一种定义形式写法,定义@Component写BookDao bookDao = ctx.getBean(BookDao.class);System.out.println(bookDao);// 第二种定义形式写法,定义@Component("bookDao")写BookDao bookDao1 = (BookDao) ctx.getBean("bookDao");System.out.println(bookDao1);}}

结果均为

com.example.demo.dao.impl.BookDaoImpl@3a52dba3 基于@Component的衍生注解

@Controller:表现层定义bean @Service:业务层定义bean @Repository:数据层定义bean 比如,在BookServiceImpl类上就使用@Service进行定义;在BookDaoImpl类上就使用@Repository进行定义,加括号的规则@Component类似,调用的方式也和原本的类似

2. Spring v3.0 纯注解开发

既然是纯注解开发,就需要删除之前冗余的这个配置文件,纯注解开发将配置的xml文件转换为了一个配置类

第一步:创建配置类

配置类写法为,实际上就是用两个注解来替代了原本配置文件中的内容:

package com.example.demo.config;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;@Configuration@ComponentScan("com.example.demo")public class SpringConfig {}

配置文件中的内容分别被配置类中的内容替代,如下: 假如想扫描多个包,使用{}来写即可,如:@ComponentScan({"com.example.demo.dao", "com.example.demo.service"})

第二步:导入配置类

将原本的加载配置文件的ClassPathXmlApplicationContext换成了加载配置类AnnotationConfigApplicationContext,里面的参数是注解类名称.class,即读取这个注解类,剩下getBean的操作和原来一样。

package com.example.demo;import com.example.demo.config.SpringConfig;import com.example.demo.dao.BookDao;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class DemoApplication {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);BookDao bookDao = ctx.getBean(BookDao.class);System.out.println(bookDao);}} 3. Bean的作用范围(单例/多例)与生命周期 Bean的作用范围

之前配置Bean的作用范围是在配置文件里通过指定scope属性定义的: scope="singleton/prototype"

<bean id="bookDao" name="dao" class="com.example.demo231116.dao.impl.BookDaoImpl" scope="prototype" />

因为Bean默认是单例模式,如果我们想要修改成多例模式,就在类上加@Scope注解,括号的内容写prototype为多例,singleton为单例

package com.example.demo.dao.impl;import com.example.demo.dao.BookDao;import org.springframework.context.annotation.Scope;import org.springframework.stereotype.Component;@Repository@Scope("prototype")public class BookDaoImpl implements BookDao {@Overridepublic void save() {System.out.println("Book Dao Save...");}} Bean的生命周期

之前提到,Bean的生命周期其实就是我们可以定义在Bean加载的时候初始化一些资源,在销毁前销毁一些资源,在配置文件中写初始化和销毁是通过init-method和destroy-method实现的:

<bean id="bookDaoCycle" class="com.example.demo231116.dao.impl.BookDaoImpl" init-method="init" destroy-method="destroy" />

在注解开发中,我们只需要在类中写好初始化和销毁方法,并分别加上PostConstruct(注解后执行init方法)和PreDestroy(销毁前执行destroy方法)两个注解,注意,初始化和销毁方法的方法名是任意的:

package com.example.demo.dao.impl;import com.example.demo.dao.BookDao;import org.springframework.context.annotation.Scope;import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;import javax.annotation.PreDestroy;@Repository//@Scope("prototype")public class BookDaoImpl implements BookDao {@Overridepublic void save() {System.out.println("Book Dao Save...");}@PostConstructpublic void init(){System.out.println("init...");}@PreDestroypublic void destroy(){System.out.println("destroy");}}

注意,如果提示没找到注解的话需要在pom.xml中导入坐标:

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

然后再执行主方法:

package com.example.demo;import com.example.demo.config.SpringConfig;import com.example.demo.dao.BookDao;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class DemoApplication {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);BookDao bookDao = ctx.getBean(BookDao.class);System.out.println(bookDao);}}

执行的结果为:

init...com.example.demo.dao.impl.BookDaoImpl@7eac9008

没有调用Destroy方法的原因是没有关闭IoC容器/注册关闭钩子,只需要像之前一样在程序结束前使用ctx.close()或通过ctx.registerShutdownHook()来注册关闭钩子 (该方法注意不能使用ApplicationContext类,因为没有close()方法和registerShutdownHook()方法)

package com.example.demo;import com.example.demo.config.SpringConfig;import com.example.demo.dao.BookDao;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class DemoApplication {public static void main(String[] args) {AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);//方法二ctx.registerShutdownHook();BookDao bookDao = ctx.getBean(BookDao.class);System.out.println(bookDao);//方法一ctx.close();}}

注意:非单例模式不会执行destroy,因为多例模式下Spring不负责销毁。Spring默认是单例的,它只管单例的销毁而不管多例的销毁

4.依赖注入 引用类型注入

依赖注入使用自动装配的方式,这里阉割掉了配置文件中的Setter注入、构造注入等等一系列冗杂的方法,使用自动装配。

@Autowire属性默认按类型注入

这里注入很简单,只需要在属性上加上@Autowire注解,就能够实现自动装配,这里的自动装配是基于暴力反射实现的,也无需再BookDaoImpl中实现set方法

package com.example.demo.service.impl;import com.example.demo.dao.BookDao;import com.example.demo.service.BookService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;@Servicepublic class BookServiceImpl implements BookService {@AutowiredBookDao bookDao;@Overridepublic void save() {System.out.println("Book Service Save...");bookDao.save();}}

假如我有两个类实现了BookDao.java这个类:BookDaoImpl和BookDaoImpl2,这时候再执行自动装配会报错,因为基于类型反射得到的类不唯一

按类型注入反射结果不唯一,按名注入

针对这种不唯一的情况,给两个类的@Repository注解后加名字,BookDaoImpl和BookDaoImpl2分别为@Repository("bookDao")和@Repository("bookDao2"):

package com.example.demo.dao.impl;import com.example.demo.dao.BookDao;import org.springframework.stereotype.Repository;@Repository("bookDao")public class BookDaoImpl implements BookDao {@Overridepublic void save() {System.out.println("Book Dao Save...");}} package com.example.demo.dao.impl;import com.example.demo.dao.BookDao;import org.springframework.stereotype.Repository;@Repository("bookDao2")public class BookDaoImpl2 implements BookDao {@Overridepublic void save() {System.out.println("Book Dao Save...2");}}

此时,假如我们在Service中的属性定义是

@AutowiredBookDao bookDao2;

则会注入对应BookDaoImpl2这个类,如果写的是bookDao1则会注入对应BookDaoImpl这个类 以上其实就是说明,Spring注解开发中,如果按类型注入不成功,就会按名注入,这些都是自动的,无需人为配置按类型注入/按名注入

按名注入的标准写法(少用)

事实上,按名注入更标准的方法是使用@Qualifier注解,这种注解还是要基于给BookDaoImpl和BookDaoImpl2都在@Repository后指定了名称的情况下进行的,标准写法如下:

package com.example.demo.service.impl;import com.example.demo.dao.BookDao;import com.example.demo.service.BookService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.stereotype.Service;@Servicepublic class BookServiceImpl implements BookService {@Autowired@Qualifier("bookDao2")BookDao bookDao;@Overridepublic void save() {System.out.println("Book Service Save...");bookDao.save();}}

@Qualifier后指定你想让bookDao属性被哪个类注入,注意,该注解必须搭配@Autowired注解使用

简单类型注入

使用@Value属性完成注入,括号内写值

package com.example.demo.dao.impl;import com.example.demo.dao.BookDao;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Repository;@Repositorypublic class BookDaoImpl implements BookDao {@Value("namenamename!!!")String name;@Overridepublic void save() {System.out.println("Book Dao Save..." + this.name);}}

就这样的方法,可能会有疑问,这样写和String name = "namenamename!!!"的区别是什么? 不一样的地方在于:你注解里面的这个字符串,可能来自于外部(比如来自于外部的properties文件)

引入外部的properties文件

假如在Resource下有jdbc.properties文件,有内容:

name=namenamename!!!

那么我们需要在配置类中加载这个文件,加上注解@PropertySource,括号内是文件名:

package com.example.demo.config;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.PropertySource;@Configuration@ComponentScan("com.example.demo")@PropertySource("jdbc.properties")public class SpringConfig {}

然后在值名称上写使用${}引用即可:

package com.example.demo.dao.impl;import com.example.demo.dao.BookDao;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Repository;@Repositorypublic class BookDaoImpl implements BookDao {@Value("${name}")String name;@Overridepublic void save() {System.out.println("Book Dao Save..." + this.name);}}

假如想加载多个配置文件,使用{}来写即可,类似于@ComponentScan 但是注意:之前在配置文件里加载的时候支持使用通配符*,但这里完全不支持使用通配符! 但是加上@PropertySource("classpath:jdbc.properties")是可以的,只是不能使用通配符

5. 第三方Bean

此处以数据库连接为例,需要在pom.xml中导入坐标:

<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.16</version></dependency> 管理

在配置类中写一个方法,一般方法名为Bean的ID。然后new一个第三方对象,并返回。 在该方法上加上@Bean注解,表明该方法返回的是一个Bean

package com.example.demo.config;import com.alibaba.druid.pool.DruidDataSource;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import javax.sql.DataSource;@Configuration@ComponentScan("com.example.demo")public class SpringConfig {@Beanpublic DataSource dataSource(){DruidDataSource ds = new DruidDataSource();ds.setDriverClassName("com.mysql.jdbc.Driver");ds.setUrl("jdbc:mysql://localhost:3306/mysql");ds.setUsername("root");ds.setPassword("123456");return ds;}}

这样写就可以在主方法里像平常一样获得Bean:

DataSource dataSource = ctx.getBean(DataSource.class);System.out.println(dataSource);

但是将第三方的配置写在Spring的配置类中可能比较乱,所以我们给它新建一个文件JdbcConfig.java:

package com.example.demo.config;import com.alibaba.druid.pool.DruidDataSource;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import javax.sql.DataSource;@Configurationpublic class JdbcConfig {@Beanpublic DataSource dataSource(){DruidDataSource ds = new DruidDataSource();ds.setDriverClassName("com.mysql.jdbc.Driver");ds.setUrl("jdbc:mysql://localhost:3306/mysql");ds.setUsername("root");ds.setPassword("123456");return ds;}}

想要让这个文件被扫描到 第一种方法是在这个配置文件上加上注解@Configuration,然后在配置类中用@ComponentScan()扫描这个包: @ComponentScan("com.example.config") 第二种方法(推荐使用)无需在文件上加注解@Configuration,而是直接在配置类中加上@Import注解,并在括号内写这个新的配置文件名.class:@Import(JdbcConfig.class) 完整代码如下:

package com.example.demo.config;import com.alibaba.druid.pool.DruidDataSource;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;import javax.sql.DataSource;@Configuration//@ComponentScan("com.example.demo.config")@Import(JdbcConfig.class)public class SpringConfig {@Beanpublic DataSource dataSource(){DruidDataSource ds = new DruidDataSource();ds.setDriverClassName("com.mysql.jdbc.Driver");ds.setUrl("jdbc:mysql://localhost:3306/mysql");ds.setUsername("root");ds.setPassword("123456");return ds;}}

多个数据也使用数组模式

依赖注入 简单类型注入

只需要在类里面定义简单类型的成员变量,并在方法中使用成员变量即可,同样通过@Value()注解赋值

package com.example.demo.config;import com.alibaba.druid.pool.DruidDataSource;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import javax.sql.DataSource;@Configurationpublic class JdbcConfig {@Value("com.mysql.jdbc.Driver")String driverClassName;@Value("jdbc:mysql://localhost:3306/mysql")String url;@Value("root")String usernmae;@Value("123456")String password;@Beanpublic DataSource dataSource(){DruidDataSource ds = new DruidDataSource();ds.setDriverClassName(driverClassName);ds.setUrl(url);ds.setUsername(usernmae);ds.setPassword(password);return ds;}} 引用类型注入

假如要注入引用类型,需要在方法的参数里面写引用类型

package com.example.demo.config;import com.alibaba.druid.pool.DruidDataSource;import com.example.demo.dao.BookDao;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import javax.sql.DataSource;@Configurationpublic class JdbcConfig {@Value("com.mysql.jdbc.Driver")String driverClassName;@Value("jdbc:mysql://localhost:3306/mysql")String url;@Value("root")String usernmae;@Value("123456")String password;@Beanpublic DataSource dataSource(BookDao bookDao){bookDao.save();DruidDataSource ds = new DruidDataSource();ds.setDriverClassName(driverClassName);ds.setUrl(url);ds.setUsername(usernmae);ds.setPassword(password);return ds;}}

因为我们已经注解了这个dataSource是个Bean,所以对于方法里面的形参,Spring会自动到IoC里面查找对应的类进行注入

6. XML配置比对注解配置

协助本站SEO优化一下,谢谢!
关键词不能为空
同类推荐
«    2025年12月    »
1234567
891011121314
15161718192021
22232425262728
293031
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
搜索
最新留言
文章归档
网站收藏
友情链接