Bean的基本注解开发

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=""@Scpoebean的作用范围,值为singleton或者prototype
lazy-init@lazy是否延迟加载,取值true、false
init-method@PostConstruct初始化方法
destory-method@PreDestory销毁前执行方法

@Component的衍生注解

衍生注解描述
@RepositoryDao层类使用
@ServiceService层类上使用
@ControllerWeb层类上使用

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注解,而是通过导入实现类,而实现类中已经导入了那两个配置类,因此可以直接用。也可以自定义一个注解,在注解上导入实现类,在需要的配置类中添加自定义注解:

posted @ 2023-02-24 21:35  Liku007  阅读(40)  评论(0编辑  收藏  举报