Spring阶段性学习总结(十 四)初步了解解耦与线程安全问题

一、(程序耦合)

所谓程序耦合,就是当结对开发的时候,一个人的代码结构,会使其开发进度被其他成员的代码进度所影响,这样会造成很大的危害。

举个例子:
之前我在写普通的Java Web 程序时,我会在Service层直接调用Dao层的方法,那么 如果在开发一个大项目时,我只负责Service层,而别人负责Dao层,我直接调用他的方法,如果他没有写完,我就没有办法继续写代码,程序也无法运行。

二、程序解耦(BeanFactory方法)

可以通过写一个BeanFactory来进行反射调用,这样将需要的参数等直接写到配置文件中,不仅大大降低了代码的耦合度,还简化了代码的结构。

三、BeanFactory 的弊端

经过测试,发现使用BeanFactory时,他是用的多例模式,这样会在调用一个方法内成员时,创建多个实例,是不需要的(因为方法内成员在多线程访问时,不会受到影响,会降低程序的运行效率)

四、线程的安全问题

当定义类成员实例时,多线程访问时,会受影响,例如我在Servlet的类内定义类成员变量 a=1 每次访问时 a++ ,,当我用A浏览器首次访问时,会显示a=1,

但是当我用B浏览器再次访问时,会显示a=2 ,不同的浏览器可以代表不同 的用户的访问,所以显然在多线程访问时,定义类成员实例会严重影响线程安全。

五、以上全是个人理解,如果有理解错误,希望收到指正,谢谢。下面附上一个BeanFactory进行解耦的例子

1 public interface StudentDao {
2 
3     public void studentDao();
4 
5 }
1 public class StudentDaoImp implements StudentDao {
2     @Override
3     public void studentDao() {
4         System.out.println("我是StudentDao!!");
5     }
6 }
1 public interface StudentService {
2 
3     public void studentService();
4 
5 }
 1 import BeanFactory_Thread.BeanFactory.Factory;
 2 import BeanFactory_Thread.dao.StudentDao;
 3 
 4 
 5 public class StudentServiceImp implements StudentService {
 6     @Override
 7     public void studentService() {
 8         System.out.println("我是StudentService!!!");
 9         // StudentDao studentDao=new StudentDaoImp();
10         Factory factory = new Factory();
11         StudentDao studentDao = (StudentDao) factory.getBean("StudentDao");
12         studentDao.studentDao();
13     }
14 }
 1 import java.util.ResourceBundle;
 2 
 3 public class Factory {
 4     //通过resourceBundle读取配置文件
 5     private static ResourceBundle resourceBundle = ResourceBundle.getBundle("beanFactory_Thread");
 6 
 7     //定义getBean()函数用来获取需要的类
 8     public static Object getBean(String beanName) {
 9         //通过传递参数来获取类的路径
10         String beanPath = resourceBundle.getString(beanName);
11         Object className = null;
12         try {
13             //读取类路径,
14             // 获取类的实例 forName()是加载某个类并不能生成某各类的实例,
15             // newInstance()则是在加载了类的基础上生成某个类的实例
16             className = Class.forName(beanPath).newInstance();
17         } catch (Exception e) {
18             e.printStackTrace();
19         } finally {
20             //返回类的实例
21             return className;
22         }
23     }
24 
25 }
 1 import BeanFactory_Thread.BeanFactory.Factory;
 2 import BeanFactory_Thread.service.StudentServiceImp;
 3 
 4 public class Main {
 5     public static void main(String[] args) {
 6         Factory factory= new Factory();
 7         //避免了直接使用NEW StudentDaoImp()这种方式的的调用,没有产生依赖
 8         StudentServiceImp  studentServiceImp= (StudentServiceImp) factory.getBean("StudentService");
 9         studentServiceImp.studentService();
10     }
11 }