目录
2 @Controller+@Service+@Repository
3 @Scope+@Lazy+@PostConstruct+@PreDestroy
4 @Value+@Autowired+@Qualifier+@Resource
5 @Configuration+@ComponentScan+@PropertySource+@import
前言
之前学习 spring 框架时,我们知道实例化bean 都是依靠 spring 配置文件,在配置文件中书写一个个bean 标签,表示将要创建的对象。
本篇博客则是 使用注解的方式,平替之前使用 spring 配置文件创建对象,等操作。
Spring的注解可以代替xml配置;通俗点来讲,注解是对xml配置的平替;原先xml配置所实现的功能,现在可以使用注解实现;而且使用注解比xml配置更符合我们编码习惯,也更简单。
常用的注解
须知
以下任何demo(案例的前提)
即使我们使用各自注解代替 标签,属性啥的。但如何去解析 注解这是我们需要思考的。
以下在配置文件中写的 标签就是解析哪个包下的注解。
<?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">
<!--spring会去扫描fs包及其子包下所有的注解,并让其生效-->
<context:component-scan base-package="fs">
</context:component-scan>
</beans>
注意:
1 base-package 的属性值 是 你需要扫描哪个包下的注解
2 不要直接复制粘贴,看需要哪个补充哪个,否则很容易出问题。
3 当然了,这些最后同样会有相应注解替代 配置文件,扫描注解的标签。但需要注意任何注解的底层都是 以xml 配置文件的形式存在。
1 @Conponent注解
使用目的
@Conponent注解 就可以平替<bean>标签。
特别提醒:在使用spring注解的时候,要想使spring容器认识这些注解,我们需要在bean.xml文件中配置注解组件扫描,只有配置了组件扫描,spring才会去指定包下面扫描你使用了哪些注解,并让其生效。
<!--spring会去扫描com.frank包及其子包下所有的注解,并让其生效-->
<context:component-scan base-package="com.frank"></context:component-scan>
demo(案例)
使用 Conponent 注解 创建 person 类
person 类,Test 测试类
package fs.exerise;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
@Component("person")
public class Person {
}
class Test{
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
Object bean = context.getBean("person");
System.out.println(bean);
}
}
效果展示
注意:component 注解里的值,可以理解为表示 之前在spring 配置文件 bean 标签的id 值。
2 @Controller+@Service+@Repository
我们在实际的开发过程中是按层来进行的;为了语义上面更加明确,所以衍生出来另外三个注解来代替@Conponent。他们的作用是为了在语义上更加明确。
@Controller注解:使用在Controller层的类上面
@Service注解:使用在Service层的类上面
@Repository注解:使用在Dao层的类上面
demo(案例)
3 @Scope+@Lazy+@PostConstruct+@PreDestroy
@Scope注解:平替<bean scope="">
@Lazy注解:平替<bean lazy-init="">
@PostConstruct注解:平替<bean init-method="">
@PreDestroy注解:平替<bean destroy-method="">
demo(案例)
UserController 类
package fs.controller;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
// 相当于本类 UserController 在 配置文件的 bean 标签
@Controller("user")
// scope 属性表示作用域
@Scope(value = "singleton")
public class UserController {
public UserController() {
System.out.println("创建UserController");
}
// @PostConstruct 注解表示初始化方法
@PostConstruct
public void init () {
System.out.println("UserController初始化");
}
// @PreDestroy 注解表示销毁方法
@PreDestroy
public void destroy () {
System.out.println("UserController销毁");
}
}
Test 测试类
package fs.controller;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test {
public static void main(String[] args) {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("spring.xml");
UserController userController = (UserController) app.getBean("user");
// 关闭 spring 容器
app.close();
}
}
效果展示
4 @Value+@Autowired+@Qualifier+@Resource
平替bean标签注入时的标签
原先使用xml实现注入的时候使用的是<property>标签来指明注入的关系;现在我们可以通过下面的注解来替换它。
@value注解:使用在字段或者方法上面,用于注入普通数据
@Autowired注解:使用在字段或者方法上面,用于注入引用数据(默认按照byType方式进行注入)
@Qualifier注解:使用在字段或者方法上面,搭配@Autowired根据名称进行注入
@Resource注解:使用在字段或者方法上面,根据类型或者名称进行注入
demo(案例)
userController 类
package fs.controller;
import fs.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
// 相当于本类 UserController 在 配置文件的 bean 标签
@Controller("user")
// scope 属性表示作用域
@Scope(value = "singleton")
public class UserController {
@Autowired
// @Autowired 注解表示自动注入 一般适用于 成员变量
// @Qualifier 可以为 @Autowired 注解的补充,表示注入的bean的id
@Qualifier("userService")
private UserService userService;
// @Value 注解表示注入值
@Value("dj")
private String name;
public void a(){
System.out.println(userService+"他的名字是"+name);
}
public UserController() {
System.out.println("创建UserController");
}
// @PostConstruct 注解表示初始化方法
@PostConstruct
public void init () {
System.out.println("UserController初始化");
}
// @PreDestroy 注解表示销毁方法
@PreDestroy
public void destroy () {
System.out.println("UserController销毁");
}
}
疑问:@Autowired注解是根据类型进行注入的,那如果我有多个UserDao类型呢?
答:所以这个时候@Qualifier注解的作用就起来了,它的作用是当发现你使用了@Autowired注解后,却有多个相同的类型,可以通过@Qualifier注解指定其中的一个名字进行注入(按名字注入)。
看案例:
我再新建一个UserDaoImp2类,让该类也去实现UserDao接口,重新观察 UserController 类
UserDaoImp1 类package fs.Dao.impl; import fs.Dao.UserDao; import org.springframework.stereotype.Repository; @Repository("UserDao1") public class UserDaoImp1 implements UserDao { }
UserDaoImpl2 类package fs.Dao.impl; import fs.Dao.UserDao; import org.springframework.stereotype.Repository; @Repository("UserDao2") public class UserDaoImpl2 implements UserDao { }
UserController 类
发现 ,因为存在 多个 userDao 的实现类,即使使用 Autowired 注解 也不知道 选择哪一个。
因此采取办法是 使用@Qualifier注解 选择其中一个 注入 进去
注意:@Resource注解:不给参数的时候相当于@Autowired进行注入;给了参数相当于@Autowired+@Qualifier
5 @Configuration+@ComponentScan+@PropertySource+@import
@Configuration 注解: 平替bean.xml文件
@ComponentScan 注解: 平替 <context:component-scan base-package="com.frank">
@PropertySource("jdbc.properties") 注解: 平替 <context:property-placeholder location="classpath:jdbc.properties">
@Import(MyDataSource.class)注解:平替 <import resource="classpath:">
注意:
bean.xml文件都被配置类给替换了,那么我在写测试类创建容器对象的时候就不能用
new ClassPathXmlApplicationContext(“bean.xml”)了;而是选择使用new AnnotationConfigApplicationContext(SpringConfig.class)。
demo(实例)
person 类
package fs.exerise;
import org.springframework.stereotype.Component;
@Component("person")
public class Person {
}
扫描所写注解的类
package fs.exerise;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
// @Configuration 注解表示当前类是一个配置类,用来代替xml配置文件
@Configuration
// @ComponentScan 注解表示扫描包,用来代替xml配置文件
// basePackages 属性表示扫描的包
@ComponentScan(basePackages ="fs.exerise")
public class SpringConfigration {
}
Test 测试类
package fs.exerise;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class test {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfigration.class);
Object bean = context.getBean("person");
System.out.println(bean);
}
}
效果展示