基于注解实现ioc注解
1.声明Bean的注解 @Component
2.包扫描
第一步:修改文件头
<?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:aop="http://www.springframework.org/schema/aop"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--开启注解扫描-->
<!--要扫描多个包之间可以使用空格,“,”,“;”分割
<context:component-scan base-package="com.kkb.spring.po;com.kkb.spring.dao;com.kkb.spring.service;com.kkb.spring.controller"></context:component-scan>
-->
<!--指定父包的形式来扫描多个包-->
<context:component-scan base-package="com.lr.spring."></context:component-scan>
</beans>
使用多个context:component-scan指定不同的包路径
多个包扫描,可以用空格或者逗号或者分号进行隔离,三种方式都可以用,不建议使用直接扫描父包的形式来扫描多个包。极限开发原则,因为会消耗性能。
第二步:加入注解
在User中加入注解@Component的作用相当于加入这样的标签
import org.springframework.stereotype.Component;
import java.io.Serializable;
//在类上添加注解@Component表示该类创建对象的权限交给Spring容器。注解的value属性用于指定bean的id值,value可以省略。
//@Component 不指定 value 属性,bean 的 id 是类名的首字母小写
@Component
//<bean id="user" class="com.kkb.spring.po.User">
public class User implements Serializable {
public Integer id;
private String name;
private String password;
第三步:测试效果
@Test
public void test05(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
User user = (User) context.getBean("user");
System.out.println(user);
}
修改注解
@Component(value = "user1")
运行程序报错
没有找到user类型
说明参数对应的值是注解的value值
3.其他注解
package com.lr.spring.dao;
import org.springframework.stereotype.Repository;
@Repository
public class UserDaoImpl implements UserDao {
@Override
public void addUser() {
System.out.println("Dao中输入User对象");
}
}
package com.lr.spring.dao;
import org.springframework.stereotype.Repository;
@Repository
public class UserMySQLDaoImpl implements UserDao {
@Override
public void addUser() {
System.out.println("MySQLDa");
}
}
package com.lr.spring.dao;
import org.springframework.stereotype.Repository;
@Repository
public class UserOracleDaoImpl implements UserDao {
@Override
public void addUser() {
System.out.println("OracleDao");
}
}
package com.lr.spring.controller;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
}
package com.lr.spring.service;
import org.springframework.stereotype.Service;
//接口上不起作用
@Service
public interface UserService {
void addUser();
}
测试
@Test
public void test05(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserController userController = (UserController) context.getBean("userController");
System.out.println(userController);
UserMySQLDaoImpl userMySQLDao = (UserMySQLDaoImpl) context.getBean("userMySQLDaoImpl");
System.out.println(userMySQLDaoImpl);
}
测试service类
UserService userService=(UserService) context.getBean("userService");
System.out.println(userService);
报错没有bean的名字是UserService
这些注解本质上跟@Component一样,只能在类上修饰而UserService是一个接口,我们要把注解@Service放到实现类中,在重新给它一个value值userService就可以了
mport com.lr.spring.dao.UserDao;
import com.lr.spring.dao.UserDaoImpl;
import org.springframework.stereotype.Service;
@Service("userService")
public class UserServiceImpl implements UserService {
// private UserDaoImpl userDao = new UserDaoImpl();
private UserDao userDao;
//set注入
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
ps:@Component("user1")等价于@Component(value = "user1")
只有一个值,value可以省略
4.属性注入@Vaule
package com.lr.spring.po;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.Serializable;
//在类上添加注解@Component表示该类创建对象的权限交给Spring容器。注解的value属性用于指定bean的id值,value可以省略。
//@Component 不指定 value 属性,bean 的 id 是类名的首字母小写
@Component(value = "user1")
//<bean id="user1" class="com.kkb.spring.po.User">
public class User implements Serializable {
@Value("1000")
public Integer id;
@Value("龙仁")
private String name;
@Value("1380341")
private String password;
测试效果
@Test
public void test05(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
User user = (User) context.getBean("user1");
System.out.println(user);
}
}
4 @Autowired和@Qualifier
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
User user = (User) context.getBean("user1");
System.out.println(user);
UserService userService=(UserService) context.getBean("userService");
System.out.println(userService);
//空指针异常
userService.addUser();
我们可以拿到这个 userService对象,但是调用add方法后,发生空指针异常,原因是程序走到这的时候,接口还是无法识别注解
我们需要在UserServiceImpl的逻辑处加入@Autowired 自动装配 这个注解
@Service("userService")
public class UserServiceImpl implements UserService {
// private UserDaoImpl userDao = new UserDaoImpl();
//自动装配
@Autowired
private UserDao userDao;
但是此时注意@Autowired的默认属性是byType 类型匹配
程序依旧会报错因为我们有三个bean(三个实现类),他不知道该找哪个?
@Autowired
@Qualifier("userMySQLDaoImpl")
private UserDao userDao;
组合注解 相当于把 byType改成byName
需要在引用属性上使用注解@Autowired,该注解默认使用按类型自动装配 Bean 的方式。使用该注解完成属性注入时,类中无需 setter。当然,若属性有 setter,则也可将其加到 setter 上。