常用注解总结:https://blog.csdn.net/qq_43751200/article/details/127639586
创建一个Maven项目
pom.xml添加Spring的依赖
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.2.10.RELEASEversion>
dependency>
dependencies>
resources下添加applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
beans>
添加BookDao、BookDaoImpl、BookService、BookServiceImpl类
public interface BookDao {
public void save();
}
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ..." );
}
}
public interface BookService {
public void save();
}
public class BookServiceImpl implements BookService {
public void save() {
System.out.println("book service save ...");
}
}
将配置文件中的
标签删除掉
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
只能在实体类(能够new对象)上才能添加注解,接口不可以添加
注意:@Component注解不可以添加在接口上,因为接口是无法创建对象的。
XML与注解配置的对应关系
为了让Spring框架能够扫描到写在类上的注解,需要在配置文件上进行包扫描
说明:
component-scan:
base-package指定Spring框架扫描的包路径,它会扫描指定包及其子包中的所有类上的注解。
在BookServiceImpl类上也添加@Component
交给Spring框架管理, 但是不对该类取别名。
@Component
public class BookServiceImpl implements BookService {
private BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
在App类中,从IOC容器中获取BookServiceImpl对应的bean对象,打印
@Component
public class BookServiceImpl implements BookService {
@Override
public void save() {
System.out.println("----------------------");
System.out.println("book service save ...");
System.out.println("----------------------");
}
}
对于@Component注解,还衍生出了其他三个注解@Controller
、@Service
、@Repository
这三个注解和@Component注解的作用是一样的,为了方便后期在编写类的时候能很好的区分出这个类是属于表现层
、业务层
还是数据层
的类。
@Component等
名称 | @Component/@Controller/@Service/@Repository |
---|---|
类型 | 类注解 |
位置 | 类定义上方 |
作用 | 设置该类为spring管理的bean |
属性 | value(默认):定义bean的id |
上面已经可以使用注解来配置bean, 但是依然有用到配置文件,在配置文件中对包进行了扫描,Spring在3.0版已经支持纯注解开发
创建一个配置类SpringConfig
在配置类上添加@Configuration
注解,将其标识为一个配置类,替换applicationContext.xml
@Configuration
public class SpringConfig {
}
在配置类上添加包扫描注解@ComponentScan
替换
@Configuration // 配置类注解
@ComponentScan("com.itheima") // 在配置类上添加包扫描注解
public class SpringConfig {
}
public class AppForAnnotation {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
System.out.println(bookDao);
BookService bookService = ctx.getBean(BookService.class);
System.out.println(bookService);
}
}
纯注解开发主要内容:
@Configuration注解用于设定当前类为配置类
@ComponentScan注解用于设定扫描路径,此注解只能添加一次,多个数据请用数组格式
@ComponentScan({com.itheima.service","com.itheima.dao"})
```
读取Spring核心配置文件初始化容器对象切换为读取Java配置类初始化容器对象
-- ClassPathXmlApplicationContext是加载XML配置文件 --
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
-- AnnotationConfigApplicationContext是加载配置类 --
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
@Configuration
名称 | @Configuration |
---|---|
类型 | 类注解 |
位置 | 类定义上方 |
作用 | 设置该类为spring配置类 |
属性 | value(默认):定义bean的id |
@ComponentScan
名称 | @ComponentScan |
---|---|
类型 | 类注解 |
位置 | 类定义上方 |
作用 | 设置spring配置类扫描路径,用于加载使用注解格式定义的bean |
属性 | value(默认):扫描路径,此路径可以逐层向下扫描 |
单例:注解配置@Scope(“singleton”)
非单例:注解配置@Scope(“prototype”)
@Scope
名称 | @Scope |
---|---|
类型 | 类注解 |
位置 | 类定义上方 |
作用 | 设置该类创建对象的作用范围 可用于设置创建出的bean是否为单例对象 |
属性 | value(默认):定义bean作用范围, 默认值singleton(单例),可选值prototype(非单例) |
知识点1:@PostConstruct
名称 | @PostConstruct |
---|---|
类型 | 方法注解 |
位置 | 方法上 |
作用 | 设置该方法为初始化方法 |
属性 | 无 |
知识点2:@PreDestroy
名称 | @PreDestroy |
---|---|
类型 | 方法注解 |
位置 | 方法上 |
作用 | 设置该方法为销毁方法 |
属性 | 无 |
小结
注意:@PostConstruct和@PreDestroy注解如果找不到,需要导入下面的jar包, 从JDK9以后jdk中的javax.annotation包被移除了,这两个注解刚好就在这个包中。
<dependency>
<groupId>javax.annotationgroupId>
<artifactId>javax.annotation-apiartifactId>
<version>1.3.2version>
dependency>
构造函数注入
、setter注入
对应的注解,只提供了自动装配的注解实现。环境准备
创建一个Maven项目
pom.xml添加Spring的依赖
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.2.10.RELEASEversion>
dependency>
dependencies>
添加一个配置类SpringConfig
@Configuration
@ComponentScan("com.itheima")
public class SpringConfig {
}
添加BookDao、BookDaoImpl、BookService、BookServiceImpl类
public interface BookDao {
public void save();
}
@Repository
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ..." );
}
}
public interface BookService {
public void save();
}
@Service
public class BookServiceImpl implements BookService {
private BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
创建运行类APP
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
BookService bookService = ctx.getBean(BookService.class);
bookService.save();
}
}
报错,bookDao为空指针
在BookServiceImpl类的bookDao属性上添加@Autowired
注解
@Service("bookService")
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
// public void setBookDao(BookDao bookDao) {
// this.bookDao = bookDao;
// }
@Override
public void save() {
System.out.println("book service ...");
bookDao.save();
}
}
注意:
写在属性上并将setter方法删除掉
问题提出: 如果我这里再建一个类BookDaoImpl2来实现BookDao,运行结果咋么样???
运行结果:报错NoUniqueBeanDefinitionException
如何解决呢?
当根据类型在容器中找到多个bean, 注入参数的属性名又和容器中bean的名称不一致,这个时候该如何解决,就需要使用到@Qualifier
来指定注入哪个名称的bean对象。
@Qualifier注解后的值就是需要注入的bean的名称。
注意:@Qualifier不能独立使用,必须和@Autowired一起使用
指定BookDaoImpl类:
指定BookDaoImpl2类:
简单类型注入的是基本数据类型或者字符串类型,下面在BookDaoImpl
类中添加一个name
属性,用其进行简单类型注入
@Repository("bookDao")
public class BookDaoImpl implements BookDao {
@Value("lsm")
private String username;
@Value("1000")
private int connectCounts;
@Override
public void save() {
System.out.println("book dao save ..." + username +", " + connectCounts);
}
}
运行结果:
@Value
一般会被用在从properties配置文件中读取内容进行使用
步骤1:resource下准备properties文件
步骤2: 使用注解加载properties配置文件
在配置类上添加@PropertySource
注解,加载配置文件
@Configuration
@ComponentScan("com.itheima")
@PropertySource({"jdbc.properties", "msg.properties"})
public class SpringConfig {
}
步骤3:使用@Value读取配置文件中的内容
@Repository("bookDao")
public class BookDaoImpl implements BookDao {
@Value("${username}") // 使用Value读取properties配置文件中的值
private String username;
@Value("${connectCounts}")
private int connectCounts;
@Override
public void save() {
System.out.println("book dao save ..." + username +", " + connectCounts);
}
}
步骤4:运行程序
这里输出的username不正确,是系统的username,注解的解决方法暂时没有找到,XML配置文件的方式解决方案如下:
<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:property-placeholder location="jdbc.properties,jdbc2.properties" system-properties-mode="NEVER"/>
beans>
注意:
如果读取的properties配置文件有多个,可以使用@PropertySource
的属性来指定多个
@PropertySource({"jdbc.properties","xxx.properties"})
@PropertySource
注解属性中不支持使用通配符*
,运行会报错
@PropertySource({"*.properties"})
@PropertySource
注解属性中可以把classpath:
加上,代表从当前项目的根路径找文件
@PropertySource({"classpath:jdbc.properties"})
XML配置和注解之间的对比