Spring注解开发
基础使用
可以使用@Component
替换标签,注解的value参数就是bean中的id,并且如果注解只有一个属性,那么这里的value就可以不写。
// 如果这个value参数不写则是根据当前类名配置id,并且类名首字母小写
@Component(value = "userDao")
public class UserDaoImpl implements UserDao {
}
但是如果只是这样写并不能够让Spring识别到这个注解,所以需要在xml文件中增加一些配置,包括
<!-- 注解组件扫描,扫描指定的基本包及其子包下的类,识别使用@Component的类 -->
<context:component-scan base-package="com.itheima"/>
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Object userDao = applicationContext.getBean(UserDao.class);
System.out.println(userDao);
}
各类注解
// 如果这个value参数不写则是根据当前类名配置id,并且类名首字母小写
@Component(value = "userDao")
@Scope("singleton") // 作用范围
@Lazy(value = false) // 是否延迟加载
public class UserDaoImpl implements UserDao {
public UserDaoImpl(){
System.out.println("UserDao创建");
}
// 这里需要注意的是这部分注解在JDK11中已经被移出,所以需要但如引入jar包或者替换JDK,可以在依赖中加入javax.annotation-api进行处理
@PostConstruct
public void init(){
System.out.println("userDao的初始化方法");
}
@PreDestroy
public void destroy(){
System.out.println("userDao的销毁方法");
}
}
@Component的衍生
其实作用都是一直的,只是在层级功能上进行区分
@Component衍生注解 | 说明 |
---|---|
@Respository | 在Dao层类上使用 |
@Service | 在Service层类上使用 |
@Controller | 在Web层类上使用 |
依赖注入注解
Value
// 如果这个value参数不写则是根据当前类名配置id,并且类名首字母小写
@Component(value = "userDao")
@Scope("singleton") // 作用范围
@Lazy(value = false) // 是否延迟加载
public class UserDaoImpl implements UserDao {
// @Value("11111")
private String username;
@Override
public void show() {
System.out.println(username);
}
// set方法如果使用注解方式进行开发其实可以不写,直接在username上添加注解,但是这种方法都是直接写死参数的并没有什么意义
@Value("222222")
public void setUsername(String username) {
this.username = username;
}
}
可以通过properties文件继续动态参数的输入,但是相应的需要配置文件
@Value("${jdbc.driver}")
private String username;
<context:property-placeholder location="classpath:jdbc.properties"/>
Autowired、Qualifier和Resource
@Component("userService")
public class UserServiceimpl implements UserService {
// 这里Autowired通过类型直接进行注入,同样这个注解也可以放在对应的set方法上,如果有多个userdao类型,那么就会根据名称进行匹配
@Autowired
private UserDao userDao;
@Override
public void show() {
System.out.println(userDao);
}
}
Qualifier
@Autowired
@Qualifier("userDao2") // 这里,Qualifier适合Autowired一起使用的,作用是根据名称进行Bean的注入
private UserDao userDao;
Resource
@Resource(name = "userDao2") // 不指定名称参数时,根据类型注入等同于autowire,如果有name参数,那么就是根据名称进行注入
private UserDao userDao;
PS:
// Auto并不是一定要加在Set方法后面,其他方法也是可以的
@Autowired
public void xxx(UserDao userDao){
System.out.println("xxx:" + userDao);
}
// 这样写将会把Spring容器中所有的UserDao类型都注入到这个List中
@Autowired
public void yyy(List<UserDao> userDaoList){
System.out.println("yyy:" + userDaoList);
}
非自定义Bean的配置
可以通过Bean标签进行设置
// 要求对应的类需要被放入到Spring容器中
// 通过Bean标签,这个方法的返回值将会被放入到Spring容器中,并且id为dataSource,并且会有默认名称,就是方法名
@Bean("dataSource")
// 通过@value可以实现参数的动态注入
public DataSource dataSource(
@Value("${jdbc.driver}") String driverClassName,
// @Autowired UserDao userDao, //根据类型进行参数注入
@Qualifier("userDao2") UserDao userDao // 可以使用autowired,但是也可以用Qualifier指定名称,并且这里和属性注入不一样,可以直接使用Qualifier
){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClassName);
System.out.println(driverClassName);
System.out.println(userDao);
return dataSource;
}
Spring配置类的开发
// 标注当前类是一个配置类(替代配置文件)
// 并且也有@Component的作用
@Configuration
// <context:component-scan base-package="com.itheima"/>
// @ComponentScan作用就和上面这个配置标签一个,base-package是一个数组,可能需要多个包
@ComponentScan(basePackages = {"com.itheima"})
// <context:property-placeholder location="classpath:jdbc.properties"/>
// PropertySource就是上面这个标签,同样可以是多个
@PropertySource({"classpath:jdbc.properties"})
// 加载其他配置类
@Import(OtherBean.class)
public class SpringConfig {
}
public class ApplicationContextTest {
public static void main(String[] args) {
// 这个是通过加载配置文件的形式实现spring的配置
// ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// 通过配置类时间Spring的配置
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
Object userDao = applicationContext.getBean("userDao");
System.out.println(userDao);
}
}
其他注解
@Primary
就是在面对相同类型的Bean的时候具有优先被使用权,自定义或者非自定义Bean都可以,并且如果使用了Primary,在使用autowired的时候,也同样会优先返回子啊有primary标签的类,不再进行名字匹配
@Component(value = "userDao2")
@Primary
public class UserDaoImpl2 implements UserDao {
}
@Profile
用于指定类注入的环境,如果在使用Spring时不指定使用该环境那么这个类将不会被加入到Spring容器中。
@Component(value = "userDao")
@Profile("test")
public class UserDaoImpl implements UserDao {
}
public static void main(String[] args) {
System.setProperty("spring.profiles.active","test");
// 通过配置类时间Spring的配置
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
Object userDao = applicationContext.getBean("userDao");
System.out.println(userDao);
}
Spring注解整合mybatis
// 标注当前类是一个配置类(替代配置文件)
// 并且也有@Component的作用
@Configuration
// <context:component-scan base-package="com.itheima"/>
// @ComponentScan作用就和上面这个配置标签一个,base-package是一个数组,可能需要多个包
@ComponentScan(basePackages = {"com.itheima"})
// <context:property-placeholder location="classpath:jdbc.properties"/>
// PropertySource就是上面这个标签,同样可以是多个
@PropertySource({"classpath:jdbc.properties"})
// 加载其他配置类
@Import(OtherBean.class)
// Mybatis Mapper的接口扫描,由Mybatis-spring提供
@MapperScan
public class SpringConfig{
@Bean
public DataSource dataSource(
@Value("${jdbc.driver}") String driver,
@Value("{jdbc.url}") String url,
@Value("${jdbc.username}") String username,
@Value("${jdbc.password}") String password
){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
@Bean
//这里的参数输入不需要特别的说明,自动会进行类型注入
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean;
}
}