spring 学习路线梳理(二)注解
1.通过注解的方式创建bean
1.1 定义dao层的接口和实现
public interface ILoginDao {
public String login();
}
@Slf4j
@Repository
public class LoginDaoImpl implements ILoginDao {
public LoginDaoImpl(){
System.out.println("spring create bean call");
}
@Override
public String login() {
log.info("{}","login validator send dao");
return "login success !!!";
}
}
1.2 定义service层的接口和实现
public interface ILoginService {
public String login();
}
@Slf4j
@Service("loginService")
public class LoginServiceImpl implements ILoginService , InitializingBean, DisposableBean {
public ILoginDao iLoginDao;
// //通过set方法 注入 需要的dao
// public void setiLoginDao(ILoginDao iLoginDao) {
// this.iLoginDao = iLoginDao;
// }
// 构造器注入
LoginServiceImpl(ILoginDao iLoginDao){
this.iLoginDao = iLoginDao;
}
@Override
public String login() {
log.info("{}","login validator send service");
iLoginDao.login();
return "login success !!!";
}
//销毁之前的操作
@Override
public void destroy() throws Exception {
System.out.println("destroy");
}
//初始化之前的操作
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet");
}
}
@Component 组件注解 下面又有3个衍生注解
定义dao的是 @Repository
定义service的是 @Service("loginService") // 可以指定value,如果没有指定需要按照类型从容器中取bean
定义controller的是 @Controller
1.3 在xml文件中配置需要扫描的包
引入扫描的 空间 context ,定义扫描的包
1.4 获取容器,从容器中拿到需要的bean
public class SpringSecurityDemoApplication {
public static void main(String[] args) {
//SpringApplication.run(SpringSecurityDemoApplication.class, args);
ClassPathXmlApplicationContext xct
= new ClassPathXmlApplicationContext("applicationContext.xml");
ILoginService bean = (ILoginService) xct.getBean("loginService");
String login = bean.login();
System.out.println(login);
xct.close();
}
}
如果没有在注解中指定别名,获取bean的时候会报错。需要通过类型获取bean
service注解中指定的别名注释掉
获取bean的时候按照别名获取
下面是报的错误
通过类型获取 (正常)
2.从spring 3.0开始纯注解开发,没有xml配置
将xml中的配置全部用注解的方式替换
2.1定义一个配置类
@Configuration //定义注解的配置类
@ComponentScan("com.drawing") //定义需要扫描的包
public class SpringConfig {
}
2.2 将获取容器的实现类换成通过注解的方式获取
2.3 运行正常
创建bean的方式没有变化,通过构造方式创建
2.4通过注解方式处理初始化之前的操作和销毁之前的操作
2.4 需要按照单利或多例创建类,只需要在类上加入
@Scope("prototype") 注解指定就可以
3.自动注入需要的bean
@Slf4j
@Service
public class LoginServiceImpl implements ILoginService {
//@Autowired
public ILoginDao iLoginDao;
// //通过set方法 注入 需要的dao
// public void setiLoginDao(ILoginDao iLoginDao) {
// this.iLoginDao = iLoginDao;
// }
// 构造器注入
LoginServiceImpl(ILoginDao iLoginDao){
this.iLoginDao = iLoginDao;
}
@Override
public String login() {
log.info("{}","login validator send service");
iLoginDao.login();
return "login success !!!";
}
}
留下构造器,将@Autowired注释掉可以正常运行
将构造器和@Autowired同时注释掉,只留下 set方法 提示空指针异常,dao没有注入
将 @Autowired 留下 构造器注释掉 是可以正常注入成功。
总结:可以通过构造器注入或者 @Autowired 加set方法注入(简写只留下@Autowired不写set方法也可以)。
4.有多个实现类的方式
4.1 定义多个dao的接口和实现
public interface ILoginDao {
public String login();
}
实现 类 1
@Slf4j
@Repository("ILoginDao1")
public class LoginDaoImpl implements ILoginDao {
public LoginDaoImpl(){
System.out.println("spring create bean call");
}
@Override
public String login() {
log.info("{}","login validator send dao 1");
return "login success !!!";
}
}
实现 类 2
@Slf4j
@Repository("ILoginDao2")
public class LoginDaoImpl2 implements ILoginDao {
public LoginDaoImpl2(){
System.out.println("spring create bean call");
}
@Override
public String login() {
log.info("{}","login validator send dao 2");
return "login success !!!";
}
}
4.2 service中的注入 编译报错
4.3 定义多个dao层的实现执行报错,提示不是唯一的
4.4 解决
在service注入中加入 @Qualifier 指定注入bean的名称
5.注解管理第三方的bean
定义bean
在spring的配置文件中导入bean,就是添加到容器中。剩下就是注入使用。