Bean基本注解开发
bean里面不需要配置,在类上加注解:@Component(bean的id)
@Component("userService")
public class UserServiceImpl implements UserService {
@Override
public void show() {
System.out.println("show方法");
}
}
在bean加上包扫描对象,让它扫描到注解
<context:component-scan base-package="com.liku"/>
然后再getBean,调用show方法,可以运行。
但是bean标签上面还有一些属性,scope、lazy、destory等等,通过下面注解来修改配置:
xml配置 | 对应注解 | 描述 |
scpoe="" | @Scpoe | bean的作用范围,值为singleton或者prototype |
lazy-init | @lazy | 是否延迟加载,取值true、false |
init-method | @PostConstruct | 初始化方法 |
destory-method | @PreDestory | 销毁前执行方法 |
@Component的衍生注解
衍生注解 | 描述 |
@Repository | Dao层类使用 |
@Service | Service层类上使用 |
@Controller | Web层类上使用 |
spring注解进行属性注入
注解 | 描述 |
@Value | 用于注入普通数据,放在属性定义上,或者set方法上 |
@Autowired | 根据类型(byType)注入引用数据 |
@Qualifier | 结合@Autowired,根据名称注入 |
@Resource | 根据类型或名称进行注入 |
@Value("${driver}")
private String userName;
@Value("张三")
public void setUserName(String userName) {
this.userName = userName;
}
当只有一个UserDao类型的时候可以根据类型找,但是有多个实现类的时候,当把注解放在变量上面的时候,它内部会自动生成一个set方法,然后根据属性名不同会取得不同的对象
@Autowired
private UserDao dao2;//查到的时Impl2实现类
把他放在set方法上是按照参数名字取匹配
@Autowired
public void setUserdao(UserDao dao1) {
//当有多个daoImpl时,set形参里面的名字会取得不同的对象
this.userdao = dao1;//查到的是Impl1实现类
当我set的时候,参数给集合,他会识别所有的类型为UserDao的类
@Autowired
public void setUserdao(List<UserDao> daoList) {
System.out.println(daoList);//打印出所有的userDaoImpl
}
@Resource,不指定名称参数时,一句类型注入,指定name的时候就根据名称匹配
@Resource(name="dao2")
private UserDao dao;
@Resource
private UserDao dao;
非自定义bean:类上面需要加component注解,不然扫描不到这个bean,方法名上加注解bean
@Component
public class BeanFactoryTest {
@Bean("dataSource")
public DataSource getDataSources(@Value("${driver}") String driverClassName,
@Qualifier("dao2") UserDao userDao,
UserService userService) {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(driverClassName);
System.out.println(userDao);
System.out.println(userService);
return druidDataSource;
}
}
在bean注解里面可以配置id,如果不加的话默认id为方法名,如果想要注入参数,也可以通过注解传参
配置类
看application.xml的配置内容目前就两个:扫描仪,读取配置文件
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--扫描指定包,产生Mapper对象存储到spring容器-->
<context:component-scan base-package="com.liku"/>
创建配置类,在上面添加注解:
package com.liku.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
//扫描指定包下面的component
@ComponentScan({"com.liku.dao","com.liku.service"})
//读取配置文件源
@PropertySource({"classpath:jdbc.properties"})
//导入外部配置类
@Import(BeanFactoryTest.class)
public class BeansConfig {
}
然后再次试试取出之前用注解设置的bean,可以正常取出!
其他注解
@Primary:设置bean优先被使用,当类型相同的时候,优先使用有这个注解的
@Profile:环境切换,只有激活了当前环境被标注的bean才会被注册到spring容器,相当于
<beans profile="test"> //只有在test环境下才会被激活
激活指定环境可以通过
命令行动态参数激活
-Dspring.profiles.active=test
使用代码激活
System.setProperty("spring.profiles.active","test");
没有标注profile的环境在任何环境下都可以使用
利用注解方式集成Mybatis
配置类:
//标记为配置类
@Configuration
//扫描指定包下面的component
@ComponentScan({"com.liku.dao", "com.liku.service"})
//读取配置文件源
@PropertySource({"classpath:jdbc.properties"})
@MapperScan("com.liku.mapper")
public class BeansConfig {
@Bean//数据源对象
public DataSource dataSource(
@Value("${driver}") String driver,
@Value("${url}") String url,
@Value("${user}") String username,
@Value("${pwd}") String password
) {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(driver);
druidDataSource.setUrl(url);
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
return druidDataSource;
}
@Bean//将sqlsession交给spring管理
public SqlSessionFactoryBean sessionFactoryBean(DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean;
}
}
mapper层:
@Repository("sysuserMapper")
public interface SysuserMapper {
/**
* 查询所有用户信息
* @return
*/
List<Sysuser> selectAll();
}
service层:
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
private SysuserMapper sysuserMapper;
@Override
public void show() {
sysuserMapper.selectAll().forEach(System.out::println);
}
}
测试:
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeansConfig.class);
UserService userService = applicationContext.getBean("userService",UserService.class);
userService.show();
}
除了可以在类上加@import(配置类.class)注解的方式加载外部配置类,还可以通过实现接口的方式:
1、实现ImportSelector接口重写selectImports方法,在配置类上的注解导入该类
public class Config3 {
@Bean//将sqlsession交给spring管理
public SqlSessionFactoryBean sessionFactoryBean(DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean;
}
}
public class ImportBean2 implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{Config3.class.getName()};//导入配置类
}
}
//标记为配置类
@Configuration
//扫描指定包下面的component
@ComponentScan({"com.liku.service"})
//读取配置文件源
@PropertySource({"classpath:jdbc.properties"})
@MapperScan("com.liku.mapper")
@Import({ImportBean.class})
public class BeansConfig {
@Bean//数据源对象
public DataSource dataSource(
@Value("${driver}") String driver,
@Value("${url}") String url,
@Value("${user}") String username,
@Value("${pwd}") String password
) {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(driver);
druidDataSource.setUrl(url);
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
return druidDataSource;
}
}
2、实现ImportBeanDefinitionRegistrar接口,重写里面的注册方法:
@ComponentScan({"com.liku.dao"})
public class BeansConfig2 {
}
public class ImportBean implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
BeanDefinition definition=new RootBeanDefinition();
definition.setBeanClassName(BeansConfig2.class.getName());
registry.registerBeanDefinition("configClass2",definition);//导入配置类
}
}
在配置类上导入该类:
@Import({ImportBean.class,ImportBean2.class})
上面两个类都没有添加@configuration注解,而是通过导入实现类,而实现类中已经导入了那两个配置类,因此可以直接用。也可以自定义一个注解,在注解上导入实现类,在需要的配置类中添加自定义注解: