一、给注解分个类
spring的注解可以用来干什么?怎么用?我们先回忆下在xml中的配置以及作用
<bean id="id" calss="com.xxx" scope="xxx" init-method="xxx" destroy-method="xxx">
<property name="xxx" value="xxx"/ref="xxx"/>
</bean>
上面的配置我们很熟悉,通过上面xml的配置,我们可以将注解的配置大致分为四类:
-
用于创建对象的
作用和xml配置中标签的功能一样
-
用于注入数据的
作用和xml配置中标签的功能一样
-
用于改变作用范围的
作用和xml配置中标签使用scope属性功能一样
-
和生命周期相关的
作用和xml配置中标签使用init-method 和 destroy-method属性功能一样
我们分别来看每种注解
二、用于创建对象的注解
在使用创建对象的注解之前,我们还需要做一些简单的配置工作,我们需要告诉spring我们在哪里使用了注解,这样spring在创建容器时会去扫描指定的包。配置如下
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--告知spring创建容器时需要扫描的包,需要导入context命名空间的约束-->
<context:component-scan base-package="com.zxwin"/>
</beans>
使用注解@Component
标识的类,spring在创建容器时会对其实例化并存储到容器中。
@Component
的属性只有value()用来指定获取对象时的id相当于标签的id属性,如若value()属性的值为空则默认为类名首字母小写。
@Component("userService")
public class UserServiceImpl implements UserService {
@Override
public void login(String username, String password) {
System.out.println("Service : login");
userMapper.selectUser(username,password);
}
}
@Component
衍生的注解,下面3个注解和@Component
的功能属性一模一样,是spring为我们提供用来明确三层架构的注解
@Controller
:用于表现层@Service
:用于业务层@Repository
:用于持久层
三、用于注入数据的注解
@Autowired
@Autowired
注解:自动按照类型注入,只要容器中有唯一一个bean对象类型和要注入的类型一致时即可注入成功。
如果容器中没有任何bean对象类型和要注入的类型一致时则出错。
如果容器中有多个bean对象类型和要注入的类型一致时,会先根据类型圈定出类型匹配的bean对象,然会后使用要注入的属性名称作为id在圈定的bean对象中按id查找,如果可以找到注入成功,找不到注入失败。
@Qualifier
@Qualifier
注解:在按照类型注入的基础上再按照名称注入,名字需要同个value()属性指定,它在给类成员注入时不能单独使用,要配合@Autowired
使用,在给方法参数注入时可以单独使用
@Resource
@Resource
注解:直接按照bean的id注入,需要通过name()属性指定id,可以独立使用。
以上3个注解都注入其他bean类型,而不能注入基本数据类型和String。复杂数据类型之只能通过xml方式注入
@Value
@Value
注解:用于注入基本数据类型和String类型数据,通过value()数值指定数据的值,该属性还可以使用spring中SpEL(${表达式})
四、用于改变作用范围的注解
可以使用注解@Scope
来改变bean的作用范围,通过value()属性来指定。
value()属性常用值:singleton,prototype
五、和生命周期相关的
@PostConstuct
注解用于指定初始化方法
@PreDestroy
注解用于指定销毁方法
这两个注解的只能作用与方法上
六、使用纯注解模式配置
我们可以通过纯注解模式配置spring,我们先来看一段xml的配置方式,让后将xml中的配置完全等价的转为注解配置
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--告知spring创建容器时需要扫描的包-->
<context:component-scan base-package="com.zxwin"/>
<!--加载jdbc配置properties文件-->
<context:property-placeholder location="dataSource.properties"/>
<bean id="userMapper" class="com.zxwin.mapper.impl.UserMapperImpl"/>
<bean id="userService" class="com.zxwin.service.imple.UserServiceImpl"/>
<bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
<constructor-arg name="ds" ref="dataSource"/>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
</bean>
</beans>
现在我们要通过纯注解模式将上面xml中配置的功能实现
使用纯注解模式需要创建一个配置类(包名,类中可自定义),多数的配置会在此配置类上使用注解配置。我们来看一下实现。
@Configuration //该注解表示当前类是spring的配置类
@ComponentScan(basePackages = {"com.zxwin"}) //用来扫描指定包的注解
@PropertySource("classpath:dataSource.properties")
public class SpringConfiguration {
@Value("${jdbc.driverClass}") //注入数据,可以使用SpEl表达式
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.user}")
private String user;
@Value("${jdbc.password}")
private String password;
@Bean("queryRunner") //添加了@Bean注解的方法会被添加到Ioc容器中,方法的返回值是Bean的类型
@Scope("prototype") //配置当前Bean的范围
//实例化该对象需要的注解可以通过形参传递
public QueryRunner createQueryRunner(/*@Qualifier("dataSource")*/DataSource dataSource){
return new QueryRunner(dataSource);
}
@Bean("dataSource")
public DataSource createDataSource(){
ComboPooledDataSource dataSource = new ComboPooledDataSource();
try {
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(user);
dataSource.setPassword(password);
} catch (PropertyVetoException e) {
e.printStackTrace();
}
return dataSource;
}
}
对上面配置中的注解具体说明:
@Configuration
:该注解表示当前类是spring的配置类
@ComponetScan
:该注解用来扫描指定包,相当于xml配置中的<context:component-scan/>
@PropertySource
:该注解用来读取外部properties配置文件
@Bean
:添加了@Bean注解的方法会被添加到Ioc容器中,方法的返回值是Bean的类型
@Scope
:配置当前Bean的范围