Spring有三种配置的方法:在Spring2.5以前,用XML的方式来配置。在Spring2.5以后,用XML+annotation(注解)。在Spring3.0以后,用JavaConfig(配置类)+annotation(注解)
现在主要说一下使用JavaConfig+annoation方式的配置
我们以一个小项目来进行讲解:
首先在数据库中建表,int aid 主键自增非空、varchar aname 非空、varchar amoney 非空。
打开IDEA创建maven项目首先导入依赖
<dependencies>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- dbutil -->
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.4</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<!-- 数据源 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
</dependencies>
创建实体类Account
int aid、String aname、String amoney
分别创造好该实体类的有参构造、无参构造、set和get方法以及toString()
然后在该类之前进行注解依赖注入@Component(value=“xxx”)注意,在此value可不写,vaule值是注入Spring容器后,该实体类的id当value没写的时候,该实体类的id(符合命名规范时)默认为该实体类的类名且首字母小写。比如如下的Account类在注入时没有写value值,Account在Spring容器中的id就是account。
Account实体类
@Component
public class Account {
private int aid;
private String aname;
private String amoney;
public Account() {
}
public Account(int aid, String aname, String amoney) {
this.aid = aid;
this.aname = aname;
this.amoney = amoney;
}
public int getAid() {
return aid;
}
public void setAid(int aid) {
this.aid = aid;
}
public String getAname() {
return aname;
}
public void setAname(String aname) {
this.aname = aname;
}
public String getAmoney() {
return amoney;
}
public void setAmoney(String amoney) {
this.amoney = amoney;
}
@Override
public String toString() {
return "Account{" +
"aid=" + aid +
", aname='" + aname + '\'' +
", amoney='" + amoney + '\'' +
'}';
}
}
在这之后,我们开始写dao层、service层、controller层
要三层的调用,则在controller层中的实现类中要将service注入,service中要将dao注入
使用@Autowired注解来注入autowired还有一个属性是required属性,默认为true,意为是否进行强制装配。
@Autowired是用来替换DI实现JavaBean注入
用来修饰成员变量或者对应的构造方法
含义:按照通过构造方法进行“类型装配”,构造方法可省略
注意:
1.默认是按照类型装配且同构造方法
2.若Spring容器中有一个类型可以与之匹配则装配成功,若没有则报错 NoSuchBeanDefinitionException
3.若Spring容器中有多个类型可与之进行匹配,则自动切换为按照名称装配,若没有名称与之 对应,则报错NoUniqueBeanDefinitionException
其他注解:
1.@Primary
含义:首选项,当类型冲突的情况下,被此注解修饰的类型将变成首选(备胎转正)
修饰:类
注意:不可单独使用,需要搭配@Component使用。
2.@Qualifier(value=“名称 ”)
含义:按照名称装配
修饰:类
注意:不可单独使用,需要搭配@Autowired使用
3.@Resource(name=“名称”)
含义:按照名称装配
修饰:类
注意:可单独使用
4.@Scope
含义:配置作用域
修饰:类
注意:不能单独使用,需要搭配@Component使用。
@Scope("prototype")
@Scope("singleton")
@PostConstruct:初始化,修饰方法 替换:init-method
@PreDestroy:销毁,修饰方法 替换:destory-method
Dao层
IAccountDao
public interface IAccountDao {
public void add(Account account);
public void deleteById(int aid);
public void update(Account account);
public Account selectById(int id);
public List<Account> selectAll();
}
AccountDaoImpl
@Repository
public class AccountDaoImpl implements IAccountDao{
@Autowired
QueryRunner queryRunner;
public AccountDaoImpl() {
}
public AccountDaoImpl(QueryRunner queryRunner) {
this.queryRunner = queryRunner;
}
public void setQueryRunner(QueryRunner queryRunner) {
this.queryRunner = queryRunner;
}
@Override
public void add(Account account) {
try {
queryRunner.update("insert into account(aname,amoney) values (?,?)",account.getAname(),account.getAmoney());
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
@Override
public void deleteById(int aid) {
try {
queryRunner.update("delete from account where aid=?",aid);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
@Override
public void update(Account account) {
try {
queryRunner.update("update account set aname=?,amoney=? where aid=?",account.getAname(),account.getAmoney(),account.getAid());
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
@Override
public Account selectById(int id) {
try {
return queryRunner.query("select * from account where aid=?",new BeanHandler<Account>(Account.class),id);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
@Override
public List<Account> selectAll() {
try {
return queryRunner.query("select * from account",new BeanListHandler<Account>(Account.class));
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/**
* @author LRONG
* @version 1.0
* @since 2024/7/16
*/
public static interface IAccountController {
}
Service层
public interface IAccountService {
public void add(Account account);
public void deleteById(int aid);
public void update(Account account);
public Account selectById(int id);
public List<Account> selectAll();
}
AccountServiceImpl
@Service
public class AccountServiceImpl implements IAccountService{
@Autowired
IAccountDao dao;
public AccountServiceImpl() {
}
public AccountServiceImpl(IAccountDao dao) {
this.dao = dao;
}
@Override
public void add(Account account) {
dao.add(account);
}
@Override
public void deleteById(int aid) {
dao.deleteById(aid);
}
@Override
public void update(Account account) {
dao.update(account);
}
@Override
public Account selectById(int id) {
return dao.selectById(id);
}
@Override
public List<Account> selectAll() {
return dao.selectAll();
}
}
controller层
IAccountController
public interface IAccountController {
public void add(Account account);
public void deleteById(int aid);
public void update(Account account);
public Account selectById(int id);
public List<Account> selectAll();
}
AccountControllerimpl
@Controller
public class AccountControllerimpl implements IAccountController{
@Autowired
IAccountService service;
public AccountControllerimpl() {
}
public AccountControllerimpl(IAccountService service) {
this.service = service;
}
@Override
public void add(Account account) {
service.add(account);
}
@Override
public void deleteById(int aid) {
service.deleteById(aid);
}
@Override
public void update(Account account) {
service.update(account);
}
@Override
public Account selectById(int id) {
return service.selectById(id);
}
@Override
public List<Account> selectAll() {
return service.selectAll();
}
}
我们可以看到,在controller的实现类中将service的实体类进行了装配,在service层的实现类中,我们将dao的类进行了装配,在dao层的实现类中将QueryRunner进行了装配。
在此,我们创建ApplicationCofig.class
首先使用@Configuration来修饰,使得该类变成Spring的配置类
使用@ComponentScan(basePackages = "com.ape")定义包扫描
@PropertySource("jdbc.properties")导入jdbc的信息
然后我们使用EL表达式将jdbc的信息分别给driver属性进行赋值。
注入queryRunner以及c3p0数据源
@Configuration
@ComponentScan(basePackages = "com.ape")
@PropertySource("jdbc.properties")
public class ApplicationConfig {
@Value("${driver}")
private String driver;
@Value("${url}")
private String Url;
@Value("${user}")
private String user;
@Value("${pwd}")
private String pwd;
@Bean
public QueryRunner queryRunner() throws Exception {
return new QueryRunner(ds());
}
@Bean
public DataSource ds() throws Exception {
ComboPooledDataSource ds = new ComboPooledDataSource();
ds.setDriverClass(driver);
ds.setJdbcUrl(Url);
ds.setUser(user);
ds.setPassword(pwd);
Connection connection = ds.getConnection();
System.out.println(connection);
connection.close();
return ds;
}
}
最后使用junit来进行测试
public class test01 {
AnnotationConfigApplicationContext annotationConfigApplicationContext = null;
IAccountController accountControllerimpl = null;
@Before
public void beforeMethod(){
annotationConfigApplicationContext = new AnnotationConfigApplicationContext(ApplicationConfig.class);
accountControllerimpl = (IAccountController) annotationConfigApplicationContext.getBean("accountControllerimpl");
}
@After
public void afterMethod(){
annotationConfigApplicationContext.close();
}
@Test
public void add(){
accountControllerimpl.add(new Account(4,"小bai","200"));
}
@Test
public void delete(){
accountControllerimpl.deleteById(4);
}
@Test
public void update(){
accountControllerimpl.update(new Account(3,"xb","2000"));
}
@Test
public void selectAll(){
List<Account> accounts = accountControllerimpl.selectAll();
accounts.forEach(System.out::println);
}
@Test
public void selectById(){
Account account = accountControllerimpl.selectById(1);
System.out.println(account);
}
}