Spring 注解开发
Spring注解开发需要先引入约束,配置扫描包,打开注解
<?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/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="com.jojo"></context:component-scan>
<context:annotation-config></context:annotation-config>
</beans>
新建User类
public class User {
public String name = "张三";
}
进行测试
public void test(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
User user = (User) applicationContext.getBean("user");
System.out.println(user.name);
}
输出结果
张三
可见注解已经生效
注意 我们示例中的@Component是没有加name属性的,但是也能通过getBean(“user”)获取到javabean,这是因为当一个组件在某个扫描过程中被自动检测到时,会根据那个扫描器的BeanNameGenerator 策略生成它的bean名称。默认情况下,任何包含 name值的Spring“典型”注解 (@Component、@Repository、 @Service和@Controller) 会把那个名字 提供给相关的bean定义。如果这个注解不包含name值或是其他检测到的组件 (比如被自定义过滤器发现的),默认bean名称生成器会返回小写开头的非限定(non-qualified)类名。
属性注入
使用@value注解注入属性
//修改User类中的代码
@Component("user2")
public class User {
@Value("张三")
public String name;
}
进行测试
public class Test {
@org.junit.Test
public void test(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
User user = (User) applicationContext.getBean("user2");
System.out.println(user.name);
}
}
输出
张三
@Component衍生的三个注解
1. @Controller web层
2. @Service service层
3. @Repository dao层
这三个衍生注解作用一致,只是针对于不同的层级
@Component("user")就相当于<bean id="user" class="com.jojo.User">
@scope
规定bean作用域
//为user类添加@Scope注解
@Component("user2")
@Scope("singleton")
public class User {
@Value("张三")
public String name;
}
测试
public void test(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
User user = (User) applicationContext.getBean("user2");
User user2 = (User) applicationContext.getBean("user2");
System.out.println(user==user2);
}
输出 true
可见,单例模式生效了
小tips
我们可以看到使用注解开发时,配置了两行代码
<context:component-scan base-package="com.jojo"></context:component-scan>
<context:annotation-config></context:annotation-config>
其中,如果xml与注解结合开发,那么scan扫描可以不加。scan扫描的作用就是扫描类上的注解,若不加scan,则需要在xml中配置bean。
基于Java类进行配置
实际开发中,可以既不使用xml文件,也不使用注解,只通过Java类来实现JavaBean的注册
新建一个User类
@Component //未标明name默认为非限定类型首字母小写
@Scope("singleton")
public class User {
@Value("张三")
public String name;
}
新建一个配置类
@Configuration //相当于一个xml文件
public class JavaConfig {
@Bean
public User user(){ //通过方法注册一个bean,方法名相当于id
return new User();
}
}
新建一个测试类
public class Test {
@org.junit.Test
public void test(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(JavaConfig.class);
User user = applicationContext.getBean("user",User.class);
User user2 = applicationContext.getBean("user",User.class);
System.out.println(user==user2);
}
}
结果输出为true
该类并未在xml中配置,而是通过Java类的方式去实现注册
若有多个Java配置文件该如何导入呢
新建Dog类、Person类
@Component
public class Dog {
@Value("猫猫")
String name;
public void show(){
System.out.println(name+"汪汪汪");
}
}
@Component
public class Person {
@Value("张三")
String name;
@Autowired
Dog dog;
public void show(){
dog.show();
System.out.println(name);
}
}
新建配置类JavaConfig2,导入JavaConfig类
@Configuration
@Import(JavaConfig.class)
public class JavaConfig2 {
@Bean
public Dog dog(){
return new Dog();
}
@Bean
public Person person(){
return new Person();
}
}
进行测试
public void test2(){
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(JavaConfig2.class);
Person person = applicationContext.getBean("person",Person.class);
person.show();
User user = applicationContext.getBean("user",User.class);
System.out.println(user.name);
}
输出:
猫猫汪汪汪
张三
张三
可见,通过Import注解,已将JavaConfig中的配置导入到JavaConfig2中