注解和xml混合开发遗留问题
想一想能不能将以下这些bean的配置都从xml中去掉,并且最终将xml也去掉。如果可以,那我们就可以脱离xml配置了。
- 注解扫描配置(能不能去掉)
<!--开启注解并扫描指定包中带有注解的类-->
<context:component-scan base-package="com.kkb.spring.service"/>
<context:property-placeholder src=""></context:property-placeholder>
- 非自定义的bean配置(比如:SqlSessionFactory和BasicDataSource配置)
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlsessionFactoryBean">
<property name="dataSource" value=“dataSource”></property>
</bean>
-
去掉xml后,如何创建ApplicationContext
之前创建ApplicatioContext否是通过读取xml文件进行创建的。
@Configuration
相当于spring的xml配置文件
从spring3.0开始可以使用@Configuration定义配置类,可以替换xml配置文件
配置类内部包含有一个或多个被@Bean注解的方法,这些方法会将会被AnnotationConfigApplicationContext或者AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义对象,初始化Spring容器。
-
属性:
value:用于指定配置类的字节码
- 示例代码:
@Configuration
public class SpringConfiguration{
//spring容器初始化时,会调用配置类的无参构造函数
public SpringConfiguration(){
System.out.println("容器初始化。。。");
}
}
@Bean
相当于标签
作用为:注册bean对象,主要用来配置非自定义的bean,比如DriDridDataSource、SqlSessionFactory
@Bean标注在方法上面(返回某个实例的方法)
-
属性:
name:给当前@Bean注解方法创建的对象指定一个名称(即bean的id)。如果不指定,默认与标注的方法名称相同。
@Bean注解默认作用域为单例singleton作用域,可通过@scope(“prototype”)设置为原型作用域。
- 示例代码:
@Configuration
public class SpringConfiguration{
//spring容器初始化时,会调用配置类的无参构造函数
public SpringConfiguration(){
System.out.println("容器初始化。。。");
}
@Bean
@Scope("prototype")
public SQLSessionFactory userService(){
SQLSessionFactory sqlSessionFactory=new DefaultSqlSessionFactory();
sqlSessionFactory.setxxx();
return sqlSessionFactory;
}
}
@ComponentScan
相当于context:component-scan标签
组件扫描器,扫描@Component、@Controller、@Service、@Repository注解的类。
该注解是编写在类上面的,一般配合@Configuration注解一起使用。
-
属性:
basePackages:用于指定要扫描的包。
value:和basePackages作用一样。
-
示例代码
Bean类(Service类):
@Service
public class UserServiceImpl implements UserService{
@Override
public void saveUser(){
System.out.println("保存用户 Service实现类");
}
}
配置类:
@Configuration
@ComponentScan(basePackages="com.sping.service")
public class SpringConfiguration{
public SpringConfiguration(){
System.out.println("容器初始化。。。")
}
}
@PropertySource
相当于context:property-placeholder标签
编写在类上面,作用是加载properties配置文件
-
属性
value[]:用于指定properties文件路径,如果类路径下,需要写上classpath
- 示例代码
@Configuration
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig{
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
/**
*创建一个数据源,并存入spring容器中
*@return
*/
@Bean(name="dataSource")
public DataSource createDataSource(){
try{
ComboPooledDataSource ds=new ComboPooledDataSource();
ds.setDriverClass(driver);
ds.setJdbcUrl(url);
ds.setUser(username);
ds.setPassword(password);
return ds;
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
properties文件:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///spring
jdbc.username=root
jdbc.password=root
@Import
相当于spring配置文件中的标签
用来组合多个配置类,在引入其他配置类,可以不再用@Configuration注解,当然写上也没问题
-
属性
value:用来指定其他配置类的字节码文件
- 实例代码:
@Configuration
@ComponentScan(basepackages="com.spring")
@Import({jdbcConfig.class})
public class SpringConfiguration{
}
@Configuration
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig{
}
创建纯注解方式上下文容器
- java应用(ApplicationConfigApplicationContext)
ApplicationContext context=new AnnotationConfigApplicationContext(SpringConfiguration.class);
UserService userService=context.getBean(UserService.class);
userService.saveUser();
- web应用(AnnotationConfigApplicationContext)
<web-app>
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
com.spring.test.SpringConfiguration
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>