xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0modelVersion> <groupId>com.mingqigroupId> <artifactId>springAnnoiocartifactId> <version>1.0-SNAPSHOTversion> <packaging>jarpackaging> <dependencies> <dependency> <groupId>org.springframeworkgroupId> <artifactId>spring-contextartifactId> <version>5.0.2.RELEASEversion> dependency> <dependency> <groupId>commons-dbutilsgroupId> <artifactId>commons-dbutilsartifactId> <version>1.4version> dependency> <dependency> <groupId>com.microsoft.sqlservergroupId> <artifactId>sqljdbc4artifactId> <version>4.0version> dependency> <dependency> <groupId>c3p0groupId> <artifactId>c3p0artifactId> <version>0.9.1.2version> dependency> <dependency> <groupId>junitgroupId> <artifactId>junitartifactId> <version>4.10version> dependency> dependencies> project>
2、使用@Component 注解配置管理的资源
/** * 账户的业务层实现类 */ @Component("accountService") public class AccountServiceImpl implements IAccountService { private IAccountDao accountDao; public void setAccountDao(IAccountDao accountDao) { this.accountDao = accountDao; } } /** * 账户的持久层实现类 */ @Component("accountDao") public class AccountDaoImpl implements IAccountDao { private DBAssit dbAssit; }
xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.mingqi">context:component-scan> <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype"> <constructor-arg name="ds" ref="dataSource">constructor-arg> bean> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/> <property name="jdbcUrl" value="jdbc:sqlserver://localhost:1433;DatabaseName=test"/> <property name="user" value="sa"/> <property name="password" value="123sa"/> bean> <bean id="usersDao" class="com.mingqi.dao.impl.UsersDaoimpl"> <property name="runner" ref="runner">property> bean> <bean id="usersService" class="com.mingqi.service.impl.UsersServiceImpl"> <property name="usersDao" ref="usersDao">property> bean> beans>
4、常用注解
(1)用于创建对象的 相当于:
① @Component
作用:把资源让 spring 来管理。相当于在 xml 中配置一个 bean。
属性:value:指定 bean 的 id。如果不指定 value 属性,默认 bean 的 id 是当前类的类名。首字母小写。
② @Controller @Service @Repository 他们三个注解都是针对一个的衍生注解,他们的作用及属性都是一模一样的。他们只不过是提供了更加明确的语义化。
基于注解的 spring IoC 配置中,bean 对象的特点和基于 XML 配置是一模一样的,但是还是需要spring的xml配置文件,name能不能不写这个bean.xml,所有的配置都用注解来实现呢?
(6)新注解说明
①@Configuration 作用:用于指定当前类是一个 spring 配置类,当创建容器时会从该类上加载注解。获取容器时需要使用AnnotationApplicationContext(有@Configuration 注解的类.class)。
/* spring 的配置类,相当于 bean.xml 文件 */ @Configuration public class SpringConfig { }
/* spring 的配置类,相当于 bean.xml 文件 */ @Configuration @ComponentScan("com.mingqi") public class SpringConfig { private DataSource dataSource; private QueryRunner runner; /** * 注入dataSource * @return */ @Bean(name="dataSource") public ComboPooledDataSource createDataSource() { try { ComboPooledDataSource ds = new ComboPooledDataSource(); ds.setUser("sa"); ds.setPassword("123sa"); ds.setDriverClass("com.microsoft.sqlserver.jdbc.SQLServerDriver"); ds.setJdbcUrl("jdbc:sqlserver://localhost:1433;DatabaseName=test"); return ds; } catch (Exception e) { throw new RuntimeException(e); } } /** * 创建一个QueryRunner 并放入bean容器中 * @param dataSource * @return */ @Bean(name="runner") public QueryRunner runner(DataSource dataSource) { //this.dataSource = dataSource; return new QueryRunner(dataSource); } }
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; @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.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url=jdbc:sqlserver://localhost:1433;DatabaseName=test
jdbc.username=sa
jdbc.password=123sa
@Configuration @PropertySource("classpath:com/mingqi/config/jdbc.properties") public class JdbcConfig { } @Configuration @ComponentScan("com.mingqi") @Import({ JdbcConfig.class}) public class SpringConfig { }
(6) 通过注解获取容器:
(7) 在测试类中,每个测试方法都有以下两行代码:
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
IAccountService as = ac.getBean("accountService",IAccountService.class);
针对上述问题,我们需要的是程序能自动帮我们创建容器。一旦程序能自动为我们创建 spring 容器,我们就无须手动创建了,问题也就解决了。
@RunWith(SpringJUnit4ClassRunner.class) public class AccountServiceTest { } @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations= {"classpath:bean.xml"}) public class AccountServiceTest { } /* @ContextConfiguration 注解: locations 属性:用于指定配置文件的位置。如果是类路径下,需要用 classpath:表明 classes 属性:用于指定注解的类。当不使用 xml 配置时,需要用此属性指定注解类的位置。 */
③ 使用@Autowired 给测试类中的变量注入数据
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations= {"classpath:bean.xml"}) public class AccountServiceTest { @Autowired private IAccountService as ; }