spring源码学习(三)spring复习之注解开发
1 @Component

1.1示例
//命名为userDao,不命名,默认为userDaoImpl,即类名首字母小写
@Component("userDao")
public class UserDaoImpl implements UserDao {
}
开启注解,扫描指定包及其包的子包
<context:component-scan base-package="com.cdc"></context:component-scan>
测试:
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Object user = applicationContext.getBean("userDao ");
System.out.println(user);
}
想扫描其他目录的包时,可以用逗号隔开

配置文件配置的bean会覆盖注解配置的bean



2 作用范围、懒加载等


3 @Component的衍生注解

4 @Value
4.1 示例一
直接注入,没有set方法
@Component("userDao")
public class UserDaoImpl implements UserDao {
@Value("abcd")
private String userDaoName;
}
结果:

4.2示例二
@Component("userDao")
public class UserDaoImpl implements UserDao {
private String userDaoName;
@Value("abcd")
public void setUserDaoName(String userDaoName){
this.userDaoName=userDaoName;
}
}
- 很少用
4.3 示例三
常用
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

@Component("userDao")
public class UserDaoImpl implements UserDao {
@Value("${jdbc.driver}")
private String userDaoName;
}
4.4 结合@PropertySource
4.4.1

4.4.2
@Configuration
@ComponentScan("com.cdc")//
@PropertySource("classpath:jdbc.properties")
@Import(OtherBean2.class)//导入(配置)一个bean
public class SpringConfig {
}
4.5使用注意

5 @Autowired
5.1 示例一
根据类型注入
@Component("userService")
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
}
5.2 示例二
如果实现的接口有多个则根据属性名称,如下示例中,UserServiceImpl的属性属性名称是userDao2,则找userDao2名称的实例
@Component("userDao")
public class UserDaoImpl implements UserDao {
@Value("${jdbc.driver}")
private String userDaoName;
}
@Component("userDao2")
public class UserDaoImpl2 implements UserDao {
}
@Component("userService")
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao2;
}
- 如果根据名称也找不到,则报错,比如userDao2改为userDao3
5.3示例三
作用在方法上,注意方法的形参名称是userDao2,注入的是名称为userDao2的实例。
@Component("userService")
public class UserServiceImpl implements UserService {
private UserDao userDao;
@Autowired
public void userDao(UserDao userDao2){
this.userDao=userDao2;
}
}
5.4 示例四

5.5 该注解是通过反射注入的

6 @Qualifier
@Component("userService")
public class UserServiceImpl implements UserService {
@Autowired
@Qualifier("userDao2")
private UserDao userDao;
}
6.1 @Qualifier和@Autowired共同作用在方法上

7 @Resource
不指定名称时,按类型注入,指定名称时按名称注入
@Component("userService")
public class UserServiceImpl implements UserService {
@Resource(name = "userDao2")
private UserDao userDao;
}
8 @Bean
示例一
配置bean的类
@Component
public class OtherBean {
@Value("${jdbc.driver}")
private String driverClassName;
@Bean //如同实例工厂方法产生bean
public DataSourceDto DataSourceDto2(){
DataSourceDto dataSourceDto = new DataSourceDto();
dataSourceDto.setDriverClassName(driverClassName);
return dataSourceDto;
}
}
测试类:
public class ApplicationContextTest {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Object dataSourceDto = applicationContext.getBean("DataSourceDto2");
System.out.println(dataSourceDto);
}
}
- bean的名称就是方法名
示例二
@Component
public class OtherBean {
@Bean("dataSource")//如同实例工厂方法产生bean;可以为bean取名dataSource
public DataSourceDto DataSourceDto2(
@Value("${jdbc.driver}")String driverClassName,//在Bean注解的作用下,可以这么注入
@Autowired UserDao userDao,//在Bean注解的作用下,可以这么注入
@Autowired @Qualifier("userDao2") UserDao userDao2,//在Bean注解的作用下,可以这么注入
@Qualifier("userDao2") UserDao userDao3,//在Bean注解的作用下,也可不用搭配Autowired注解,直接使用Qualifier,按名称注入
UserService userService //在Bean注解的作用下,可以这么注入,按类型注入,如果有多个实现类那么按名称注入
){
DataSourceDto dataSourceDto = new DataSourceDto();
dataSourceDto.setDriverClassName(driverClassName);
System.out.println(userService);
return dataSourceDto;
}
}
- 上面的userService改成userService3,就会注入失败,容器里没有叫userService3的bean
示例三
搭配@Configuration

搭配@Configuration
setUserDAO处可以直接调方法注入,userService.setUserDAO(userDAO())

9 @Configuration
示例一
简单配置类:
@Configuration//标注这是个配置类,代替xml方式;另外此注解是基于@Component注解
@ComponentScan("com.cdc")//
@PropertySource("classpath:jdbc.properties")
//@ComponentScan({"com.cdc"}) 可以扫描一到多个包
//@PropertySource({"classpath:jdbc.properties"}) 可以扫描一到多个配置文件
public class SpringConfig {
}
测试类:
public class AnnotationApplicationContextTest {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
Object dataSourceDto = applicationContext.getBean("dataSource");
System.out.println(dataSourceDto);
}
}
示例二
数据库连接对象

示例三
结合FactoryBean使用


10 @Import
示例一
导入(配置)bean,bean类上无需加其他的组件注解
@Configuration
@ComponentScan("com.cdc")//
@PropertySource("classpath:jdbc.properties")
@Import(OtherBean2.class)//导入(配置)一个bean
public class SpringConfig {
}
public class OtherBean2 {
@Bean
public DataSourceDto dataSourceDto2(){
DataSourceDto dataSourceDto = new DataSourceDto();
return dataSourceDto;
}
}
- dataSourceDto也会被配置进spring
示例二
可以导入配置类

11 @ComponentScan 和 context:component-scan标签

排除策略
排除该包及其子包的User类

排除该包及其子包的标注了的Service注解的类

排除bean包及其下面的子包,只支持包切入点表达式和类切入点表达式,下面是包切入点

下面是类切入点,不管在哪个包(及其子包)下的User类,都排除

注意在配置文件里配置了bean的话,不会被排除策略排除的,下面的user始终进入单例池

叠加使用

与之对应的@ComponentScan用法


只包含策略
只扫描该包及其子包的标注了的Service注解的类

与之对应的@ComponentScan用法

配置的优先级问题
xml文件配置的bean会覆盖前面的

示例,用UserDAOImplNew实例替换调UserDAOImpl实例,体现了开闭原则




在AppConfig4中导入xml配置


@ImportResource
导入xml配置文件,程序加载AppConfig3,然后又根据AppConfig3上面的@ImportResource,加载xml配置



加载多个配置文件
扫描包及其子包

或者扫描多个包及其子包
ApplicationContext applicationContext2 = new AnnotationConfigApplicationContext("com.abc","com.efg");
配置多个配置类

浙公网安备 33010602011771号