Spring面向切面编程(AOP,Aspect Oriented Programming)
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程(也叫面向方面),可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等。使用JDK的动态代理可以实现AOP.
AOP通过代理的方式都程序动态统一添加功能
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPQAAAEqCAIAAACtDupCAAAgAElEQVR4nO2dd3Rb53n/IZKS4iknPrKWnbTHcR3H56RK7MRt/0gq2Y0cp16J4+Qk7XHanjoebaJT1XZrW9OybO1BcYgSJVEUQ1GUuERxbwIgCRCDALH33rjYgwu/P57q/q5BAry8IHhB6v3+pQE++PK9n/e5zzvuexkJJKQVKgbdBpCQsiUEN9KKFYIbacUKwY20YoXgRlqxQnAjrVghuJFWrBDcSCtWCG6kFSsEN9KK1d0I9wzSXKL7siy+7gq457yW00h3tFJZX+Fw4xxPTU1N3tEE0lzC22dqagonnu4LmJFWLNxwbYBpuHixWCwajUaj0QjSXILGicViOOtTU1PLGvGVCTeR7Hg8Ho1GQ6GQ3+/3+XwYhnm9Xo/H40a6I4/H4/V6MQzz+Xx+vz8UCkWj0Xg8vtz5XrFwT01NQbYOhUIYhrlcLpvNZjKZjEaj/o50SDod3hpGo9FkMtlsNpfLhWFYKBSCLA58031JqWgFwo3n7Gg0GgwG3W631WrV6XRyuVwsFgsEAh6Px0X6qng8nkAgEIvFcrlcp9NZrVa32x0MBqPRKJ6/6b6wC9ZKgxsfPsbj8WAw6HK56Ha0zMRisfh8vlwuNxqNLpcrGAzG43F8iEm3u4VpBcINBUkkEvF6vWazmW5Hy0wNDQ1dXV0cDkcmk5nNZq/XG4lElmlxsqLgxtN2LBYLBAIOh0OtVtNtapnp/PnzNTU1HR0dPB5PrVY7HI5AIBCLxZZj8l6BcEO1jWGYxWKRSCR0m1pmOnz4cFlZ2c2bNwcGBiQSicViwTAMKm8EN50i1iQej0ev1wsEArpNLTN9+umnJ06cqKys7OjoEAgEer3e4/Es08pkBcIdj8fD4bDb7dZoNBwOh25Ty0z/9V//dejQofPnzzc3N3M4HI1G43a7w+EwDCsR3LQJhzsUCjmdTpVKNTQ0RLepZab//M//3LdvX0lJSUNDw9DQkEqlcjqdoVAIwU2zcLiDwaDT6VQqlWw2m25Ty0zvvffenj17ioqK6uvr2Wy2Uql0Op34hCCCmzYR4XY4HAqFAsG9UL3zzju7d+8+e/ZsXV0dm81WKBQOhwPBTb9mw81iseg2tcyEw33z5k0Wi4XgzhUhuDPXH/7wh08//RQyN4I7h4TgzlzEsgTBnUNCcGcuBHeOCsGduRDcOSoEd+ZCcOeoENyZC8Gdo0JwZy4Ed44KwZ25ENw5KgR35kJw56gQ3JkLwZ2jQnBnLgR3jgrBnbkQ3Dmq5QU3447m/UCazyy6ENw5quUFd+IOvpl/ZhGF4M5R0QU3Yy7N/q+kzye+Cm6qPI3gpiwE9+KIyGtiLlJnA038wJyfnPOv2RaCO0e1vOCe/Y/p0/zSCMGdo1rucKePvDRCcOeolhfcqcoSPEjSDy6NENw5KtoHlIm54E5Taczme3Z/mDNC9oTgzlEtu6nAHBSCO0eF4M5cCO4cFYI7cyG4c1QI7syF4M5RIbgzF4I7R4XgzlwI7hzV4sKd+ewbtQhLPLGdJAR3jio34V5okDQ/kn6+PBOruBDcOaoM4Z5z5SX9MgoZEFN9JlX89J9P9bPkf830QnDnqBYxc5MhJg1YqVJsmk+m704L6nKZCMGdo1osuMkwlCbLzpmDU4GYphvM++dUH8hECO4c1aLAnQplMnDPmW7JfN2cf00VfM4+syhkJxDcOats19zETxJ/JH1AMl86+69pOliaP2QuBHeOanHLkjT/kob79HFSfYYMr6k+s4hkJxDcOaulrLmJn0wfh+S3JNLWJGk+n6ozUBOCO0e1ZJmb+I9pqFoQcEkfJp+5KXxXGiG4c1RZgjs9wZkrKX6qPpMK7nn72IKE4M5Rob0lmQvBnaNCcGcuBHeOCsGduRDcOSoEd+ZCcOeoENyZC8Gdo0JwZy4Ed44KwZ25ENw5KgR35kJw56gQ3JkLwZ2jQnBnLgR3jgrBnbkQ3DkqBHfmeuedd/bs2VNUVITgzi3NhpvNZtNtapnpvffew+Fms9kI7lwREW6n06lUKhHcC9X777+/b9++kpKShoYGNputVCqdTieCm37hcIdCIafTqVKphoaG6Da1zPSnP/3pwIEDpaWlDQ0NQ0NDKpXK6XSGQiEEN80iwu1yudRq9cjICN2mlpn++7//+4svvjh//vytW7dGRkbUarXL5UJw0y+Ae2JiIhwOu91urVY7OjpKt6llpt27d584caKioqKtrW10dFSr1brd7nA4PDExgeCmUzMzM9PT0wC3x+MxGAxCofDee++tqakpKSn58ssvd+/e/cEHH+zcufOPf/zjf9zR+9nXewS9++6777777jvvvPPuHb1D0Lvvvot/Mtuu8Bb44x//uHPnzg8++ODRRx/98ssvS0pKampquru7hUKhwWDweDwA9/T0NIKbNgHck5OT0WjU5/OZzWapVPq1r33t/vvvf+ihhx5++OENGzZs2rRp8+bNW7ZseRTpjrZs2bJ58+ZNmzZt2LChuLi4srLy1q1bLBZLKpWazWafzxeNRicnJxHcNAvgjsVigUDA4XBoNBo+n9/T09PY2FhVVVVeXl5aWlpcXHw2myq8ozNnzpw5c+bUqVMnT56Ev+7evXvbtm0vvfTSb3/723/4h3946qmnNmzY8Lvf/e748eOnTp06cuTI4cOHjx07duLEiZMnT546der06dNnzpyBaFn1XFxcXFpaWl5eXlVV1djY2NPTw+fzNRqNw+EIBAKxWAzgpvvyLkwrEG5iZWIymWQyGYfD6e3tbWlpqa+vr62trampqampuXbt2rVr12oWVRCzurq6urq6qqrq6tWrlZWV8O8nTpzYtm3bunXrtm7dum7dut///ve/+MUvtm7dumvXrvXr1//FX/zFu+++W15efvXq1bKysvLy8suXL1+5cqWysrKqqqqqqgpiZskw/Lm2tra+vr6lpaW3t5fD4chkMpPJRKxJENw0Cy+7o9FoIBBwOp0Gg0Emk/H5fDab3d/f39PT093d3dnZ2dnZ2bV46ryj9vb21tbW1tbWtrY2+K+LFy++8MIL99577zPPPPPll1/+1V/91fbt26urq8vKyjZt2vT5559funTpl7/85bp16x577LEPP/ywvb29sbHxxo0b9fX1TU1Nzc3NLS0tra2t7e3tHR0di2sbd97d3d3T09Pf389ms/l8vkwmMxgMTqczEAhEo9HlWHAnVh7cia/Omfh8PqfTaTKZ1Gq1TCYTiURCoVAgEPAXTzwej8fjjY6OcrnckZERNpvN4XD4fP7IyMinn3764x//eO3atT/84Q8LCwvZbPZbb7312GOPQXavqal56623nn766du3b9+6dauqquq3v/3tmjVrtm/fXlFRweFwmExmd3d3X18fk8lks9lDQ0MjIyNcLnd0dJTH4y3ir8Dn8wUCgVAoFIlEMplMrVabTCan0+nz+ZbpPAloZcI9PT0NE97hcNjv97vdbrvdbjabDQaDTqfTarVarVaTsdRqtVqtVqlUSqVSLpdLJBKFQqHRaORy+RdffPHoo4/ef//9v//978+dOwcdYN++ffn5+RUVFe3t7devX29oaGhoaFi/fv2RI0fa29ubm5tHRkZKSkqeeeaZgoKCHTt23Lx5UyqV8ng8LpfL5/NFItH4+LhMJlMoFEqlUqVSqdXqzH8LjUYDDaLT6QwGg9lsttvtbrfb7/eHw2GY3l6OaTuxIuFOEKZN4vF4JBIJBoN+v9/r9brdbtdiyOl0OhwOh8Nhs9ksFovRaLRYLC6Xy2KxHD9+HLDeuXMnn8/X6XRCoZDD4fT3969du/bDDz9ks9m3b99uaWlpa2sbHh5+//33t27dyufzOzo6Ojo6uFyuSCS6cuXKj370o/z8/L1796pUKovFolAo5HK5SqXS6XRGo9FsNlutVrvd7nA4nE7novxSLpfL7XZ7vV6/3x8MBiORSDweX46TJLhWJtyJRGJmZgbqE5g8iUaj4XA4FAqFQqFgBgoEAn6/3+fz+Xw+r9frcrkwDAsGgx6P5/Tp01u2bLnvvvt27doll8udTuf4+Dj3jh5//PFt27bJ5fLe3t6enp6BgQEWi8Xlcnk83vr16y9evDg2NjY4OMhms4eHh+VyucViKSsru++++zZv3nzs2DGj0eh0OrVaLXQkh8Phcrk8Hg+GYT6fLxAIBAKBTH6vYDAIjRMOh6PRKEyPQDWyTMlOrGC4E3f4hhJlcnJygqB4PB5boKLRaCQSgR4SCAQwDIM5Mr/fX1hY+Oijjz7wwAMfffSRSqXyer1yuRyKex6PJ5VK33vvvW9961tQlA8NDXE4nNHRUaFQyOfzTSbTBx988OyzzxqNRqinoQIWiUQGg0Eikezateu+++578sknWSxWIBBwuVwmk8lqtTqdTo/HA2SHQqFIJBKNRoHLhSoejxMbB7CGhL18yU6sbLgTd/jGKQdNLVDQMeLxOPAdDAbh38Ph8NmzZ7ds2fLAAw98/PHHer0+EAhoNBqZTCaRSCQSyfj4uFqtPnPmDIPB6OjoUKvVXC5XIBCMj4/L5XKomPV6vV6v37hxY21trV6vxwtruVwuk8m0Wi2GYXq9/vnnn2cwGD//+c8HBwdjsZjD4bBarXDfwOGOxWI4mhSEtw+x0ei+gBlphcONa4aS8KwPZIdCIfh3sVgMRciDDz64e/duk8kUCoX0er2CIJlMptfrNRrNPffcc/jwYbPZLBQKxWIxYG00Gq1WKzAaj8f37NnzN3/zN5FIBAaL+CBPq9XCh30+3+3bt3/84x+vWrXq1VdftVqtExMTUPpDlQx8z8671ET35Voc3S1wL1Q42RMTE7FYLBwOw78LhcLXX3+9oKDgscce++STT3CslUpl0gwGjPy+853v7NixIxAISCQSqVSqUCh0Oh0kXS9Bbrf7kUceKSoqcrvdMGo0GAwmk8lkMhmNRpjkcblcPp+vo6PjBz/4wcaNG0+ePOlyueLxOIySfT4fcRS4fKc4FlEI7mSlwfq1117Lz89//vnnu7q6MAzzer1ErCHd6vV6g8Gg1+vdbvfHH3/8xBNPGAwGqFWUSqVerweyYUYiFAr5/X6PxzM9PV1UVPTggw8ajUaj0ajX600mk8VisdvtNpvNarXCPKZWq/V6vSaT6ZNPPnnooYc2bdoEiEciEbvdDiV4KBSKRqPEiY67FnEE9/9XKqz5fP5rr722evXqn/70p93d3cFg0OFwwPQ2jjWea61Wq8Vi8fl8ly9fZjAYLBbL7XZDKaLX681mM2RZfFIiEonAMDGRSGzbtu2jjz4Kh8M6nQ5CwUwflB+AONwQ/H6/Tqfbs2fP17/+9e9973tsNhuGtg6Hw+PxQJUCK4srY2hITQjuROKrWMPSD/w7j8d79dVXk7BW3pFarYZUbTKZzGazzWZzOBx2ux1mCdetW3f27Fmfzwe1ik6nM5vNDocDw7BQKARzbVDNh8NhDMPC4XBXV9emTZv0ej0kb4gJ088wDw0z6yaTCRD3+XxGo/HFF1/My8t76aWXYKwJPQEGmuFwGEaZd2eVclfDjY8a8fkQItYvv/xyQUHBT3/6056enlAolAprWEwBBGERJBAIPP300zt27JienoaFTMjEUDkEg0F8Bylsg8GT99TU1N///d9/+OGHPp9PqVTCrDY+6+f1ej0ej9vtdjqdVqvVaDTC7QLDsI6OjhdeeCE/P/+VV16xWq2xWAz6w12O+F0KdxLWUKTCf42Ojr7yyisFBQUvvvhib29vMBi02+3E8SKONaRqWEzByZuYmDhw4MB3v/tdl8sF1TZkWavVCmvaMKeBlwr4c3FQTrS1tW3YsEEul5vNZhhKajQak8kE9QYs2fh8Po/H43A4YHFUq9VCqu7p6fn+97+/YcOGw4cPOxyOeDwO+R7GmrCWfleNNe86uFNh7fV6GxoaXn755dWrV6fBGnZf2Gw2yKYYhsHI0uPxuFyuiYmJK1euMBgMNpuNYRj+IxaLxel0Endr4GwRN+ja7fZEIvHqq6++9957v/rVr5555pmzZ8+qVCq5XG4wGOx2O9wWYKHU5/PBnhmLxQJjTbfbbTAYDhw4sH79ekDcbreHw2F8rAk3DRzxFV+I30Vwp8I6Go2eOnVq48aNGzdu/NnPftbT0+P3+202G0w5JxUhRKyhtoblPZvNBnR+/etfP336tMfjUSgUMKmXVGoTyQZLeGWi1+tPnDjx13/91/gLnH7wgx+IRKLh4WGpVIrvQQ2Hw7BWGgwGMQzDt4VBleLz+QwGw2effbZ+/frvf//7AwMDEJw4I36XTKesZLjxyzbz1UV4mAxOJBKRSOT48eMbNmx45JFHIM8FAgEca3zSmpitgQ9In36/f3JysrKy8siRIzMzMzab7amnntq2bZvP5xOLxVKpFOb+gHtiqU00iT8XNzMzc+PGjaS3k91///0XLlzo6elhs9lSqdRiscDQE9bMYUoH9gK4XC4Ya8K9AsMwg8Hwj//4j7DBsKenJxqNwpavpEJ8WW+NSq8VBTcRZeIyOzAN+0MmJiYSiUQkEjl27Bh++7bZbIFAQKfTEbGGbI1PWUBJAFkzEonABqxwOPzEE08wGIxf/epXO3fu/OEPf8jj8WDriFgsViqV+MZoYqmd5HlqagqSq8Viefzxx5P4/vd//3d4QIbD4ahUKuJzX8SlU9j2iI81wbzP5+vu7n7xxRcLCgp+/vOf22w2fNEH9nvhi/bEQpyYFOi4jIumFQI3XnIQt4JAeoPtRFDsJhKJUCh09OjRRx55ZOPGjUePHrXZbDBnTMQa39mMY028m8M2Wp/PNzMzU15eTgTx448/5nA4HR0dTCZTKBQqlUqLxQJpO825H5OTk5FIBMriioqKNWvWEGM++eSTly9frq6u7u7uFolEJpMJwzD8JkDcHQA3E+JYU6PRwNRkf3//9773vYcffvizzz6z2WxQiLvdbnxdM2lfCnGfyZJfzEXTSoCbOEuN793D96YCl4lEIhAIHDlyZP369Zs2bTp27BgUIUSs8ZkNWBqcjTUkS7wY8Hq9Tz31VFKiPXjwYEdHR09PD4/HU6lUNpsN0naquz9kbnhcH6rqV155hRjwa1/72ieffHL58uXGxkb8lBziWQtExGFfF0yn4GNNjUYDewkPHz68cePGhx9+uKKiYmpqCgpxfKwJ60qwtAR9OGmnCh3XNiMte7hn7jxUBqkLMnQwGPR6vWazORAIRCIRh8Nx8ODBb3zjGxs3bjx+/DgMy1Jh7XA43G43XpgSpxem7uwO9/v9U1NTJSUlSWTn5eXt3bu3vr6+vb2dy+Wq1Wq8ikiVthOJxPT0NMS0WCwymWxkZORv//ZviWF/+ctflpaWVldX9/X1SaVSq9UaCATi8Thevs9eW4VCHB9rwqYAn89nsVgOHTpUUFDw/PPPd3d3w5OmkMW9Xi9QDncA2GxInCNfdkPPZQz3DOFxG3hcMh6PBwKB119//cknnxweHg4Ggy0tLdu3b3/kkUc2bNhw9OhRq9Xq8/m0Wu1CscZzJP5ops1me/LJJ4kI5ufnv/POOxcuXKisrITjmiBlwllkaR4dh7DBOyfTikSiS5curV27Fo/8xBNPFBUVXbx4sa2tTSAQGAwGr9cbjUaTOkwqxJ1OJ76uCT/b19f30ksv5efnb9++vaura3JyEioZq9UKtXgwGCRuGceXVJdXCl+ucBMTNjyHkkgkmpqavvnNbwIQr7322ssvv7xq1apt27ZVVlaKxWKYtIZnENNjTSxAicMs/Lifqampf/7nf07K2W+99dbJkydPnjx59erVjo4OnEKoSdKkPYgMZbder+fz+RwO5/3338eDr1279tNPP7148WJjY+Pw8HBSZZIUKqlIw/dmEceadrvd7/f39vb+7Gc/YzAYe/bs0ev1cMDi1q1bX3755Z6eHjhJVKfTwRN0c07S57iWH9xJCRtGV263+9e//nVeXh4RuB/96EdlZWW8O+Lz+fCUAP4kIo41XnSmmR2D/Ap36tHR0dWrVxPJ/qd/+qdDhw4dOHCgqKiotra2v79fIpHADqr0NQn+G8FtByYih4eH29rann32WfwrfvOb31y8eLG2tnZgYEAmk8H0TqobAnFGH59Omb2uabPZJiYmysrKNmzY8MADD+zZs6e9vb2goIDBYKxaterSpUsajUYoFEokEq1Wa7VavV5vMBhcRil8mcE9O2FPT0/X19dv2bIlqfwtKCj46KOPbt++XVNT09LSMjAwwOPxJBKJWq2GJUM8W8N0Qfo9dPC9sVjM5/NNTk4S0zbk7EOHDu3Zs+f48eOXL1+GaTu1Wg2H/5I59ANP3l6v12g0ikSikZGRsrIyQI3BYDz99NMVFRUwZzI2NmYymeCUszTdhjjWhO2HSYs+er1erVa73W6j0fjFF19s3rw5Pz+f2IY7duwYHByEx+9lMpnRaIQUvlxOMllOcCcd2BCPxz0ez69//etVq1Yx5tI3vvENOPmuqampv79fIBAoFAqDwQATfMTaet6toXhZHI/Hx8fHceby8vL+8Ic/HD9+fN++fUePHj1//nxdXd3g4KBEIjGbzfic3bwQ4Mk7GAw6nU6NRsPlcoeGhg4cOAC/3dq1a48dO1ZbW9vW1sbj8XQ6HZwFNW9w4qJs0qIPVClwOoXVauXz+evWrUtqw+eee66oqIjJZLJYLLFYrNPpYG4RFsKg0TK6qNnUksI9k4HwcRKM4mdmZhoaGjZv3jwn1qB77rkHTuNtampiMplwbWC9ECpIuEJEsud8OgvgwI+I+MlPfoKTvXPnzpKSks8///z48ePnz5+/ceNGT0/P2NgYPKxAMm3jjQPfgmGY1WqVy+VDQ0PDw8Pbtm2Dr3v77bcbGhpu3749MjICqznE6fM0Sny1loNZf3xG3GQyqVQq2JSSKk3s379/aGhocHBQIBCo1WooUWCgnMtnCC4F3EmgUBA+iRsKhSYnJzEMe/PNN1MxvWnTpq1bt7722mv/8z//c/LkycrKytbWVi6XC0sqbrcbX7YgzvGl/3aYqpuenr548SJ8S35+/v/+7/9WVlaeOHGisLCwvLz8xo0bXV1dfD4/aQaQfOMQdwgaDAaxWMxms7u6uh5++GEGg/HMM8+0tLQ0NzezWCyZTAYFPfG2M6dm5wjijDiGYcC3yWTasWNHqiZdtWrVv/zLv9y6dWtwcJDL5SoUCrPZ7Ha78cPW5u1geDdbSmUdbiLT0LK4JsgJHxLBCvatW7c2bdqU1PqrV69+9tlnn3vuubfffnvXrl379+8/ePDgyZMny8rK6urq+vv7xWKxwWBwuVww840vUsDwMY0ZfPEPDlGAVZu8vLz9+/fX19cXFxefO3euoqLi5s2bXV1dXC4XbvEYhoHb9Fc0qXHg62D502azqVQqPp8/Ojp69OhRBoOxZs2aioqKzs5OJpMpEong5gAjvCTPxEbGuSfmF/w2GAqFMAyz2Wx6vX50dLSmpgb2Rc6J+HPPPdfQ0MBisWAjFxylApt48RSeRktPeXbhTmpNWBKPLlBQJkajUQzD3njjjSSmf/KTn/zbv/3bgQMHjh49+sUXX+zbt2/v3r0HDx48ceLEhQsXamtru7u7IZtCsQhTIvj5HvN+O9wuPB5PNBq9dOkSkH306NGurq7Lly9fvny5qqqqrq6uq6sLPxkVChKYyphOfcues3Hg6+CIQzjCk8PhiMViONph165dg4ODg4ODY2NjsLQOmw3xQ0uShJ9JkjSiwKsU4BtGsUqlks/n9/X1FRcX/+u//iuc6pbE90MPPXTo0CGhUDgyMiISiWDKBWZR8DV8kt0sq+CBsgh30n0QMMUPbSIp2Fbq9/vr6urwJv7ud7/7u9/9rrS0tKio6MqVK+fOnTtx4sSXX34Jh1sXFhaWlZVVVVU1NTX19vby+XylUgllIqRtEEkzsG0aFvBgj9Tp06eHhoauXbtWVVVVU1PT0NDQ0dHBZrPFYjFcbNi4B8ks1YVM0zj4nB0AJxQKh4eHR0dHv/Od7/zlX/4lj8fr7+/n8/kKhcJoNOIPMcx2DlsXk1ajiH6gX8W+epZ5V1dXfX19RUVFUVHRxx9//Jvf/CZpJiovL+/tt9/u6+sTCARjY2NQgsNzGBS6WVaVLbjxtETcjIFhGGzqd5IWPBhrs9nKy8vffPPNI0eO9Pb2dnR09PX1Xb9+vaKiAk6SLyoqKi0thdXB2traW7dudXV1DQ0NiUQijUaD714Kh8PEI6PmNQPPRMKjBnv37mUwGGfPnh0bG2toaKitrb1x40ZjY2N7e/vg4ODo6CgcVDLnfPDMrInFNI2Df6ler1epVGKxmMPhCASC4uLiP/3pT2w2e2BggMvljo+Pw0M68EDQbPP4eWv4ylSSH/jDxMQETEGazWaZTDY8PNze3n7t2rXz588XFhaeOnXq4MGDu3bt2r59+7e+9S0c8b/7u7/r7e0VCAQCgUCpVBqNRngkglo3y5KyCPc0YeYu1Uglc126dKmioqKqqqq2trapqamjo2NwcBBu5SqVCnacwmQ2XmNkz4xWq4Xn2/1pj0hdssaB5+fx2aHZfqa/+iIKrVYrEolYLFZ7e/uNGzcqKirOnTt39uzZM2fOlJaWHj9+/MCBA9u3b8f3LR45cmRsbEwgEMjlcngsY86eNm83y5KyAjd+z8VXWxgMhs1mg2da4ZlZ/PBcXVrBkUtyuXx8fJzP5w8NDXV3d7e0tDQ0NFy/fp3BYNTU1Ny8ebO5ubmrq4vFYvH5fIlEotFo8OdfoBTBC+gFmYGTjpVKpUQi0el0crm8v7+/u7u7vb29vb29q6sLTmsfHR0dGxtjMBgqlQp/OmH2TMKCGgemnxUKhUQiGRsbg2lvJpPJZDKHhoa4XO7Y2Bg8DwH7CIiG4ccZDAYsxKbxM0OYonG73TR2s2wou3DjK+QMBgO2F8NR1nK5HDZ4zHvItFqthg0h4xIRT20AABk5SURBVOPjAoFgZGRkYGCgu7u7tbW1ubmZwWC0tLR0dHQQ79T42SBJoxwoABZkBidMKpWOjY2Njo7CdG9/f//AwABwBkdXikQiBoMhl8s1Gg2UwnjlnQru9I0DT7jBsWzj4+NwaiYcGMvj8eBkNjjCCrcNbsGwXC5nMBiAfio/RCcwaGYwGGq1WiQScblcOPq+ra3t1q1bN2/erKmpuXr16pUrV2ChtKGhAd7K0N7ezmQy4eEM2NoAnW2h3Swbyhbc+P0OjveFXw8wlUqlxN1L+MnnqTK3RqOBh2ThGnO5XKg7e3t7GQxGf38/k8kEsmELBDQfvoRG3KpKwQzcOoBvkUgkEAjgJQpwIDy8jUAsFo+PjzMYDEilOp0ObMy5E4N848Dh9oA4HG4vFovhu+CkTJwk8Im3FXQJBoMBx1yl8pMKbolEIhAI4F4xMDDQ39/f1dXV1tbW3Nzc2NhYX19fV1fX0NDQ1NTU2tra09PDYrFGR0dFIhH8+viZ/OS7WTYgTCwB3HAiB4PB0Gg0crkcv3j4Ay+wgmBOLTgvT6fTwZWG2zQ8zcVgMEZGRng8HlTYsLKAT/3ibZeJGfh2vV6v1WrxlyjIZDL4QUixOExSqRSSN9w9iO8BmxPuef3A6WpwPhve1aH7wdk9uFtwDqcKQm+c18+c3Uyj0cBtCs5fhjeicDickZERJpMJOaW7uxveoTMwMMBms/EaCZyDwwV1s2xAmMgq3FBT+v1+p9MJKQGwgCaA3UupRvpzzlrAeWJwdKpCoYBkib/JRafTEafhpglbVTM3A99usVjgOBGcKkAKpjXgEsLJaTCQnXOPEQU/8OvbbDY4NxD+gL9WgdhK8KYHg8EAxUB6P6m6GRRCIOge0JnHx8fhpUL4m4AEAgFUR3APwfvbQrtZNiBMLCXcQCRcPJgycxLOSCAz4Q2TZc47+5Lh+kmlUmhcg8HgcDhm87QoZuDb4URWD0FutxsmK/V6PYPBgJgwQ7cguMn4geN40jvE24eMn/TdTC6XQ67FOzPcwfBRLyRpHeGQRLy/LbSbZQPCxBLDDQ+/wJyRk3DGQKqZ/zkXC/1+PzwgaDQaoZiDei5Vqy2iGVj6IQp/1MVsNjMYDKhbqMFN3s+cDvEnR8n7IdPN8FeUuN1u6M/4qYV2ux2m+eC/8F5HoZtlA8LEUsINIzONRgObTqHwStrmkV74k+dQINpsNrgYcAzDguCmy0xO+VlQN4OnNHDhrxaCf4dFX8rdLBsQJpYSbqjAoKFhUwQ+n59+Ux4ufNIDZtDsdjuOBX4lSMJNl5mc8pNJN8NPzpjd/Sh3+0XXksINJRoc65i04X2GhKbvrOrBvjmHw0EMu1C4aTGTU35yp5tlA8IELXBT/vWohc0pMznlJ3e6GZlfkIIQ3Ahu+p2QCUtBCG4EN/1OyISlIAQ3gpt+J2TCUhCCG8FNvxMyYSkIwY3gpt8JmbAUhOBGcNPvhExYCkJwI7jpd0ImLAUhuBHc9DshE5aCENwIbvqdkAlLQQhuBDf9TsiEpSAEN4KbfidkwlIQghvBTb8TMmEpCMGN4KbfCZmwFITgRnDT74RMWApCcCO46XdCJiwFIbgR3PQ7IROWghDcCG76nZAJS0EIbgQ3/U7IhKUgBDeCm34nZMJSEIIbwU2/EzJhKQjBjeCm3wmZsBSE4EZw0++ETFgKQnAjuOl3QiYsBSG4Edz0OyETloIQ3Ahu+p2QCUtBCG4EN/1OyISlIAQ3gpt+J2TCUhCCG8FNvxMyYSkIwY3gpt8JmbAUhOBGcNPvhExYCkJwI7jpd0ImLAUhuBHc9DshE5aCENwIbvqdkAlLQQhuBDf9TsiEpSAEN4KbfidkwlIQghvBTb8TMmEpiGa407xJKJOwmcM920+SMQT3IjohE5aC6IEbXpMVDoeB74mJicmvikg8+bCZw42/jQ7eNzdbuDH42NLAPW9Poxx2oS2T3kMmlykbWmq4tXdecOj1egOBALyCNkhQKBSCd9EC8UTEswo3vJBucnJyYmICPgxv405lbGpqCl5Ilz244bYGSt/TqKVhMj8Cr+qLxWLQLOk9LPQXXFFw46+mNZvNdrsd3h9utVrNZrPJZDIajSaTyWKx2O12j8dDBC6T2yjJS4i/ZT0cDvvvvF7eYrGkMgbvz43FYpFIZNHhxpGCt/HO29Pwu80iwg3vocQwLBgMzn4rdpo0dDfCrdVqVSqVSqXSaDQajUatVstkMg6HMzg42N/f39vb29PT09PTMzAwwOfzFQqFwWCA6iUajRJfX7vocDscDq/XGwwGA4GA1+u12+0ajYbH4zGZzIGBgVTG4NW6wJzP51tEuHGkQqEQBJ+3p+Gl3YLuJOlvsEaj0WazuVwur9frdrtdLpfNZkvvAe9mdx3carVaLpdLpdLx8XEej9fb2ysWiz0ez8TEBP6DExMTbrebx+Pdvn2byWRKJBKj0eh2u0OhELTdQpNTKjPE/ASXEABSq9VsNlsikXi93vTGDAaD0+nEMMzv93u93kV8PTa8cR3DMLfbbbPZ1Gr1vD0Nf88v5PgM4Var1Wq1Wq/XA8RGo1GhUIyOjg4ODqb3AGmI2mXKhpYCbrjwSqVSLBbzeLyuri4+nx8MBqenp1P9eCAQGB4ebmpq4nA4KpXK6XQGg0HITwstc9PnJ4PBYLFYrFar0WjkcDgikSgUCqVqbqKxkZERpVJpsVjcbjdQmDnc4MdsNkOOVCqVbDZ7fHx83p5mNBpdLlcgEMCTPWW44QarVCpVKpVCoRCJRAMDAyQ9QBqCAp3CaGTRlXW4fT6f3W5ftWqVVCrlcrmtra1msxmwnpycVCgUly5d2ntHly5dUigUk5OTEESn09XW1rJYLKVSCXzHYrGFlrnpBwA6nU6v12s0GjabbbVayRu7fv364OCgVCqFXGuxWIAMynBDvtTpdPAbDQ8Pk+9pkALsdjuGYVBckbmTpLrBKhQKiUQyNjbW19cnFApDodCC0lAgEIjFYgu6h2SBwURiaeC22WyrVq0SCARtbW0GgwFaym63Hzx48PHHH1+9ejXjjlavXv34448fPHjQbrcnEonp6WmNRlNdXc1isVQqlcvlgjJ3seAGvhUKBYvFwrsceWN//vOfBwYGJBKJTqczGo2ZwE3MlzKZbGBgYEE9rba2lslkyuVyi8Xi8Xjcbrfdbl8o3PgNFurGjo4OamnI4XAEAgEYgC5oNLLoyi7ckUgEwzCz2Zyfn89kMkdGRqamphKJhNlsfuONN/Lz8xlzKT8//4033jCbzYlEYnp6uqen5+bNm1wu12AwYBgWCoUW1GrpYZLL5Twej8/nUzN2/fp1FosllUo1Gs2qVatgoEwNbjAzPj7e19dnMpkopAAmkymTySwWi8PhIFMmzQk3NEh7e7vRaKSchiB/B4PBFQ631+s1Go2rV69uaWkJh8OJRMLj8bz55pt5eXlzAgTKy8t78803PR5PIpEIBoMXL15sb2+XSCR2u93v9y+o1dLAJJPJRCJRV1cXZWPl5eXNzc1cLlcmk+Xl5eGlxULh1mg0crlcLBYPDw+Pjo5S62k3btwYGhpSqVRms9lsNjPmu5PMWT2KxeKBgYFM0hCHw9Hr9W632+/3YxhGfqi96Mou3OFw2O12a7Xae++9d2hoKJFITE1NHT16dM2aNUnN9H9uCFqzZs3Ro0ehidva2qqrq4eHh/V6vcfjCQQCGIZlAjdUI+Pj4yMjIxwOZ05jyS01l7HW1tbKysqenh6hUJifnw91BQW41Wq1RCKBlJlJCmhpaREIBBqNhkyZNLt6zMvLgzFihmlofHzcYrF4vd4FzSMturIIdzweD4VCLpdLqVRu2bLFYrEkEgmJRPLtb397Ntb/5+ar+va3vy2RSBKJhFarLSkp6ezslMvldrvd5/ORb7VUMMlkMqFQ2N3dbbVaZxtLMpNkj2issLAQJk8KCgoUCoVKpdJqtQuFW6lUikQiFos1MjKSoNrT2trarl69OjAwIJVKtVotlEkk4cYwzGKx5Ofns1isDNPQn//856GhIa1W63Q6SVb/2YAwkW24g8Gg3W6XSqXbt2+Px+OJROL06dNzZoL/czMrK5w+fTqRSMTj8ZKSksbGRqFQuNCUkCZTjo6Otra2pjc2pz2isbNnz9bU1PT3969evVomkymVygXBDb+FQqHg8/nt7e1zpoAE6Z5WVFTU0tLC5/OVSuWqVavSl0lJ1aPZbC4oKEjlgfjVs68U0UNxcXFHR4dUKrVarbD0s2LhttlsYrH49ddfh//au3cvGXpw7d27F/6rpKTk2rVrHA7HYDB4PJ7M4R4fH+dwOC0tLemNpbKHGysqKrp8+XJXV9eaNWukUik1uGUyGZfLbW5uzrCnFRUVQeUtlUrnHQPMOTRK4wG+dM4rRfRQXFzc0NDA5/ONRqPdbl/JcFut1rGxsV/84hfwX5ThPnv2bGVlJZvN1ul0brfb4/FkArdKpYLRW3Nzc3pjqbzhxgoLCy9cuNDW1rZmzRqJRKJQKCjALZVKh4eHb926Na+ZOf0Qe9rVq1f7+/vFYvFC4dbr9WvWrEnlAf/Gea9UcXExDJB0Op3NZluZcMdisWAwaLFYhEJh5nAXFhZeuXKFxWJptVp8tZxMq6WBm81mzwv3vMZOnz5dVlbW2tq6du3a8fFxhUKh0WgWCrdEImGz2Y2NjWnMfOWypW6lS5cudXd3j42N5eXlqVQqknB7PB6dTrdmzZo5PRC/cd4GgTTEZDLVarXVarVarWQuUza0RJn7hRdeyLDmPnHiRDYyd2NjYxpjc7pKMnbs2LFMMjd00fHxcRaLlR7uNK5wsM6cOXPx4sXu7m6hUAhwp5m9IU5qAdxr165NBfdspYK7sLCwoqJicHBQpVLB1oYVCzfU3N/85jeNRmMixTAlFUb4MEWtVh88eDAbNXdTU5PJZJrT2JyWkoypVKr9+/dnXnND5q6vr8+w5j527FiGmXteD3M2C9HD8ePH75bMDbMlDz74YH9/f4LEJFfiTsMRJ5jq6+uPHj2ajdmSzs7OwcHB2cbmbqxZxurq6r788svMZ0ug5q6vr5+zpyW+ChPRDOOrKeDAgQMZ1tz19fUZpqHPPvts5dfcxHnue+6559q1a6FQKLHwpYFAIHDo0KHS0tJszHMzmcwbN25QNvb555+fPXs2k3lu4mxJa2vrwMBAguo8d319/eHDhzOcLWltbe3r65vTQyq4Z6ehlT9bQlyhXLt2bX19fW9vL4VF3cbGRqhJsrFCyeVyW1paBgcHqRk7cOBAhiuUxHnuvr6+69evZ5ICMp/n7uvrq66uzsRDSUnJyp/nTkoJXV1dFRUVarV6QdtxJBLJ3r17z507l729JSwWq7a2VqvVUjBWXFy8KHtLYIWSzWY3NTUNDAxQTgFVVVUZrlCy2eybN2/29fVR9lBdXb3yVyiTdgXCVFd5eTnOd/qNlNPT0zKZbP/+/adPn66vr8/erkChUNjX13ft2jWcb5LGTp06dePGjUXZFYjvLQEnGo2GQk8rLS1dlL0lnZ2dV65cySQNrfy9JbP3c/f29tbV1Z0/f76np8fv90+n2AI/PT2NYVhzc/OBAwdOnz4NG4Wzup9bKBT29vZWVVX19/eTN3b9+vXF2s+N7wrkcrmdnZ1VVVU43+RTQF1d3aLsCmSxWE1NTZcuXaKWhu6WXYGzn8Tp6+tramq6fPlyaWlpX1+fzWaDiSdQPB63WCzt7e2ff/75wYMHS0tL6+rqluZJHNjqWVtbW15e3t/fP6+xmzdvMpnMxXoSh7ifm8PhdHZ2Xr16ta+vb0E9bRH3c/f39zc2Nl68eLG3t5dCGror9nMnPeIBz1CyWKzOzs76+vqKioqioqLi4uLi4uLCwsIzZ84cP3780KFDR44cKSkpqa6ubmtr43K5S/MMpclkkslkIyMjbW1tVVVVJSUlxcXFJSUlqYxxOJxFfIYy6UkcPp/f29tbU1Nz4cIFMj2trq5u0Z/EYTKZLS0tV69eLSsrW1AauluexEkqK/Gn34VCIYfDGRgYaG1traurq66urqysrKioqKysvHbtWkNDQ2dn5/Dw8NI//a7X68fHx4eHhzs7OxsaGq5du5bK2KI//Z70DKVEIhkaGmptbSXT0yAFLO4zlCKRiMPh9PX13bp1q7KyEnLQvB6cd9UzlEnJiXhuiVKplEgkQqGQy+UODw+z2Wx4DmVsbIzec0sMBoNCoRgbGxsdHU1lLBvnliQ9/a7VasVi8dDQ0Lw9LXtPv0ulUoFAwGQy29vb6+vr03u4655+n13mohOn5r2TEM8t0ev18/a0bJ9botFoYM0rvYfoXXhuSVJyQmcFznsnQSdOLYrQKa9znGU6Tfcpr+iswEUROp875U+lUiZmKDQOOuWVstCbFZbUDLUfnLenUQ670Htaeg9ZvfoUhOBeBnBnyU/uOCETloIQ3Ahu+p2QCUtBCG4EN/1OyISlIAQ3gpt+J2TCUhCCG8FNvxMyYSkIwY3gpt8JmbAUhOBGcNPvhExYCkJwI7jpd0ImLAUhuBHc9DshE5aCENwIbvqdkAlLQQhuBDf9TsiEpSAEN4KbfidkwlIQghvBTb8TMmEpCMGN4KbfCZmwFITgRnDT74RMWApCcCO46XdCJiwFIbgR3PQ7IROWghDcCG76nZAJS0EIbgQ3/U7IhKUgBDeCm34nZMJSEIIbwU2/EzJhKQjBjeCm3wmZsBSE4EZw0++ETFgKQnAjuOl3QiYsBSG4Edz0OyETloIQ3Ahu+p2QCUtBCG4EN/1OyISlIAQ3gpt+J2TCUhCCG8FNvxMyYSkIwY3gpt8JmbAUhOBGcNPvhExYCkJwI7jpd0ImLAUhuBHc9DshE5aCENwIbvqdkAlLQQhuBDf9TsiEpSAEN4KbfidkwlIQghvBTb8TMmEpCMGN4KbfCZmwFITgRnDT74RMWApCcCO46XdCJiwFIbgR3PQ7IROWghDcCG76nZAJS0EIbgQ3/U7IhKUgBDeCm34nZMJSEIIbwU2/EzJhKQjBjeCm3wmZsBSE4EZw0++ETFgKQnAjuOl3QiYsBSG4Edz0OyETloIQ3Ahu+p2QCUtBCG4EN/1OyISlIAQ3gpt+J2TCUhCCG8FNvxMyYSkIwY3gpt8JmbAUhOBGcNPvhExYCkJwI7jpd0ImLAUhuBHc9DshE5aCENwIbvqdkAlLQQhuBDf9TsiEpSAEN4KbfidkwlIQghvBTb8TMmEpCMGN4KbfCZmwFITgRnDT74RMWApCcCO46XdCJiwFIbgR3PQ7IROWghDcCG76nZAJS0EIbgQ3/U7IhKUgBDeCm34nZMJSEIIbwU2/EzJhKQjBjeCm3wmZsBSE4EZw0++ETFgKQnAjuOl3QiYsBSG4Edz0OyETloIQ3Ahu+p2QCUtBNMBtMpkcDofP54tEIvF4fGpqCm/r9Jqenp6amorH45FIxOfzORyOzOFeYjM55QfBTUWpfj21Wq3Vak0mk91uxzAsHA7HYrHJyUm4hPNqampqcnIyFouFw2EMw+x2O4PB0Gq1arWaAty0mMkpP7nTzbIBYWIp4YaG1mg0BoPBZrN5PJ5gMAgNF4/HJ0gIPhmJRILBoMfjsdlsDAZDo9HgWJCHmy4zOeUnd7pZNiBMLCXcGo1GqVSqVCr8N8QwLBAIhMPhSCQSJaFIJBIOhwOBAIZhTqfTbDYzGAyVSqVUKjUazYLgpstMTvnJnW6WDQgTSwy3QqFQKBRqtVqv11utVqfT6fF4MAzz+Xx+EvL5fBiGeTwep9NptVr1ej2DwYCYFOCmxUxO+cmdbpYNCBNLCbdarZbL5TKZDC6hwWCwWCw2m83hcDhJy+Fw2Gw2i8ViMBjUajWDwZDJZHK5XK1WLwhuuszklJ/c6WbZgDCRVbih8AoEAi6Xi5E1SaVSuVyu0WjMZrPL5QoEAlAgJsGdI2Zyyk/udLNsQJhYArih8LJarTqdTqlUymQyqVQKbadSqTQajVar1Wq1OhKCT2o0GpVKpVAo8FBKpVKn01mtVigQ08BNu5mc8pM73SwbECayB/fMzAzMB8GQ2eFwGI1GqOfkcrlcLofrp1KpYPhCUmq1Gn5KoVBAHKjkjEajw+GAoT3MW4GHXDOTU35yp5tlA8JEtuGGW14gEIBRs9Fo1Ol0cBngepBsr6S2w6+lRqPR6XRGoxHG9YFAAG52c8KdC2Zyyk/udLNsQJjIEtyJOzdfvOH8fr/H43E4HFar1Ww2mwgyL1BJP2u1Wh0Oh8fj8fv9eJMl5YOcMpM7fnKnm2UJwizCTbzr4XNDHo/H5XKRH5qkl8vlgoE8zFUlFZS5aSan/ORIN8uSsgV3gpAYJicn4/F4NBoNh8PBYDAQCJCZUSKjQCAQDAbD4XA0Go3H47CKNmcyyCkzueMnd7pZNpRFuBOEtoN7Xzwej8ViZBYCyCsWi8HKGXHzQ+6byR0/OdLNsqHswp0gXEJ81wEuMmu5qUSMg+95mLe9cspM7vjJkW626Mo63Ik7bUe8kIsrYvzlZSZ3/ORIN1tcLQXcuGaypuVuJhf8EH+Exm62iFpSuJGWhWjvZoslBDfSihWCG2nFCsGNtGKF4EZasUJwI61YIbiRVqz+H5oklX6jp/rDAAAAAElFTkSuQmCC" alt="" />
现在要给功能4增加一些额外的行为,如处理日志,处理权限等,可以使用代理实现。我们在功能4外面包装一个对象,假设叫A,
model原来是直接调用功能4,现在model调用包装对象A,A再调用功能4,A在调用功能4之前和之后可以增加一些功能。具体参看代理模式。
aaarticlea/png;base64,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" alt="" />
模拟一下
/**
* 代理模式中的抽象角色
*/
public interface UserService {
void queryUsers();
void saveUser();
void deleteUser();
}
/**
* 代理模式中的真实角色
*/
public class UserServiceImpl implements UserService {
@Override
public void queryUsers() {
System.out.println("query users..");
} @Override
public void saveUser() {
System.out.println("save a user...");
} @Override
public void deleteUser() {
System.out.println("delete a user...");
}
}
/**
* 代理角色,需要实现同样的接口
* 这里我们给程序统一的添加了功能
*/
public class UserServiceImplProxy implements UserService { private UserService userService; //传入的是真实角色
public UserServiceImplProxy(UserService userService) {
this.userService = userService;
} @Override
public void queryUsers() {
this.pre();
userService.queryUsers();
this.post();
} @Override
public void saveUser() {
this.pre();
userService.saveUser();
this.post();
} @Override
public void deleteUser() {
this.pre();
userService.deleteUser();
this.post();
} private void pre(){
System.out.println("operations pre...");
} private void post(){
System.out.println("operations post...");
}
}
public class MainTest {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
// 使用包装之的后的代理对象
userService = new UserServiceImplProxy(userService);
userService.saveUser();
userService.deleteUser();
userService.queryUsers(); }
}
这样做有一个不好的地方,
首先,三个方法添加的功能如果是一样的,每个方法里写一遍,麻烦!
其次,接口中如果增加了方法,真实对象和代理对象都要改,新的方法添加同样的功能,再写一遍!!
改进:JDK动态代理,可以给接口中的方法统一添加功能能,而不是在每个方法中都写一遍。
public class LogJDKProxy implements InvocationHandler { //要代理的对象
private Object target; public LogJDKProxy(Object target) {
this.target = target;
} //创建代理对象
public Object createProxyObject(){
return Proxy.newProxyInstance(//
target.getClass().getClassLoader(), //
target.getClass().getInterfaces(), //
this);
} /**
* @param proxy 代理对象
* @param method 当前要执行的方法,调用谁就是谁
* @param args 方法的参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
this.before();
// 执行原方法
Object result = method.invoke(target, args);
this.after();
return result;
} private void pre(){
System.out.println("operations pre...");
} private void post(){
System.out.println("operations post...");
}
}
public class MainTest {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
// 使用包装之的后的代理对象
userService = (UserService) new LogJDKProxy(userService).createProxyObject();
// 使用包装之的后的代理对象
userService.saveUser();
userService.queryUsers();
userService.deleteUser();
}
}
执行结果
operations pre...
save a user...
operations post...
operations pre...
query users..
operations post...
operations pre...
delete a user...
operations post...
这就叫动态统一的添加功能
如果接口中增加了方法,代理对象不用变
尽管如此,动态代理还是有一个问题,就是要求被代理的对象要实现接口,因为有这么一句
target.getClass().getInterfaces(),
对于没有实现接口的类也想实现动态代理的效果要怎么办呢?
使用cglib,通过子类的方式生成代理,因为子类可以重写父类的方法,以及调用父类的方法。如
public class UserService{
public void deleteUser(){
//......
}
} public class SubUserService extends UserService{
public void deleteUser(){
this.pre();
super.deleteUser()
this.post();
}
}
代理类
public class LogCglibProxy implements MethodInterceptor {
//要代理的对象
private Object target; public LogCglibProxy(Object target) {
this.target = target;
} //创建代理对象
public Object createProxyObject() {
Enhancer enhancer = new Enhancer();
// 设置父类类型
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return enhancer.create();
} @Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy)
throws Throwable {
this.pre();
Object result = method.invoke(target, args);
this.post();
return result;
} private void pre() {
System.out.println("operations pre...");
} private void post() {
System.out.println("operations post...");
}
}
这种方式有什么限制呢,jdk动态动态只会给public的方法添加功能。那么CGLIB方式呢?
public class UserService {
public void foo1() {
System.out.println(">> public的方法 <<");
} protected void foo2() {
System.out.println(">> protected的方法 <<");
}
//子类不能访问,所以不可以使用cglib
void foo3() {
foo3();
System.out.println(">> default的方法 <<");
}
//子类不能访问,所以不可以使用cglib
private void foo4() {
System.out.println(">> private的方法 <<");
}
//不可重写方法
public static void foo5() {
System.out.println(">> static的方法 <<");
}
//不可重写方法
public final void foo6() {
System.out.println(">> final的方法 <<");
}
}
cglib的原理是子类重写了父类的方法然后添加功能,所以类不能是final的
AOP是使用代理的方式实现的,它优先使用jdk动态代理,如果没有实现接口,就使用cglib采用子类的方式。
三个重要概念:切入点,切面,通知
切入点:要拦截那些方法
通知:对于拦截的方法他要做什么事
切面 = 切入点 + 通知(对拦截的方法做什么事)
使用编程的方式实现AOP(使用接口)
public interface UserService { void queryUsers(); void saveUser(); void deleteUser();
}
public class UserServiceImpl implements UserService { @Override
public void deleteUser() {
System.out.println(">> 删除一个User <<");
} @Override
public void queryUsers() {
System.out.println(">> 查询所有User <<");
} @Override
public void saveUser() {
System.out.println(">> 保存一个User <<");
} }
通知
public class LogAdvice implements MethodInterceptor { @Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
this.pre();
// 执行原方法
Object result = methodInvocation.proceed();
this.post();
return result;
}
private void pre(){
System.out.println("operations pre..."); } private void post(){
System.out.println("operations post..."); }
}
public class MainTest { // 使用编程的方式实现AOP
@Test
public void test() throws Exception {
UserService userService = new UserServiceImpl(); // =================================================== // 1,声明"切入点",表示要拦截哪些方法
NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
pointcut.addMethodName("save*");
pointcut.addMethodName("delete*"); // 2,声明一个"通知",表示拦截到之后要做什么事
LogAdvice logAdvice = new LogAdvice(); // 3,组装为一个切面(切面=切入点+通知)
Advisor advisor = new DefaultPointcutAdvisor(pointcut, logAdvice); // 4,为原对象生成一个代理对象
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvisor(advisor); // 添加一个切面
proxyFactory.setTarget(userService); // 指定目标对象
userService = (UserService) proxyFactory.getProxy(); // 获取代理对象 // ===================================================
// 使用的是代理对象 userService.saveUser();
System.out.println(); userService.deleteUser();
System.out.println(); userService.queryUsers();
System.out.println();
}
}
Spring面向切面编程(AOP,Aspect Oriented Programming)的更多相关文章
- Java 面向切面编程(Aspect Oriented Programming,AOP)
本文内容 实例 引入 原始方法 装饰者模式 JDK 动态代理和 cglib 代理 直接使用 AOP 框架--AspectWerkz 最近跳槽了,新公司使用了 AOP 相关的技术,于是查点资料,复习一下 ...
- Spring面向切面编程(AOP)
1 spring容器中bean特性 Spring容器的javabean对象默认是单例的. 通过在xml文件中,配置可以使用某些对象为多列. Spring容器中的javabean对象默认是立即加载(立即 ...
- Spring面向切面编程(AOP)方式二
使用注解进行实现:减少xml文件的配置. 1 建立切面类 不需要实现任何特定接口,按照需要自己定义通知. package org.guangsoft.utils; import java.util.D ...
- Spring面向切面编程AOP(around)实战
spring aop的环绕通知around功能强大,我们这里就不细说,直接上代码,看着注释就能明白 需要的可以点击下载源码 1.如果使用注解的方式则需要先创建个注解类 package com.mb.a ...
- Spring学习笔记:面向切面编程AOP(Aspect Oriented Programming)
一.面向切面编程AOP 目标:让我们可以“专心做事”,避免繁杂重复的功能编码 原理:将复杂的需求分解出不同方面,将公共功能集中解决 *****所谓面向切面编程,是一种通过预编译方式和运行期动态代理实现 ...
- Spring 面向切面编程(AOP)
Spring 系列教程 Spring 框架介绍 Spring 框架模块 Spring开发环境搭建(Eclipse) 创建一个简单的Spring应用 Spring 控制反转容器(Inversion of ...
- Spring框架系列(4) - 深入浅出Spring核心之面向切面编程(AOP)
在Spring基础 - Spring简单例子引入Spring的核心中向你展示了AOP的基础含义,同时以此发散了一些AOP相关知识点; 本节将在此基础上进一步解读AOP的含义以及AOP的使用方式.@pd ...
- Spring学习手札(二)面向切面编程AOP
AOP理解 Aspect Oriented Program面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. 但是,这种说法有些片面,因为在软件工程中,AOP的价值体现的并 ...
- Spring框架学习笔记(2)——面向切面编程AOP
介绍 概念 面向切面编程AOP与面向对象编程OOP有所不同,AOP不是对OOP的替换,而是对OOP的一种补充,AOP增强了OOP. 假设我们有几个业务代码,都调用了某个方法,按照OOP的思想,我们就会 ...
随机推荐
- Azure Bill
MSDN的本月订阅的被用完了,所有的付费订阅均变成了不可用的状态. 信用额度为0元,还有2天能恢复 点击上方的MSDN订阅名会进入更加详细的账单,账单以月的形式提供. 邮件中也会通知您到了限定额度所停 ...
- Struts 2简单配置分析
要配置Struts 2,首先先要有Struts 2的Jar包,可以去Struts的官网下载(http://struts.apache.org/),这里有3个GA版本可以选择下载,我选择的是最新的2.2 ...
- 解决sublime text 2总是在新窗口中打开文件
在mac下不是很喜欢sublime text 2 总是在新窗口中打开文件,很麻烦,文件打多了,就会出现N多窗口,虽然可以直接打开当前目录可以解决,但有时候查看其它项目中的单个文件,就比较麻烦.百度一直 ...
- MAC 升级到10.10(OS X Yosemite)下apache+php的配置问题
MAC升级到最新系统后 本地测试的站点不能正常运行,其原因是mac系统升级后 他的apache的版本也随之升级了版本 Server version: Apache/2.4.9 (Unix) Serve ...
- std::function赋值的几种方法
定义: #include <functional> std::function<void(const QString&)> myPrintFunction; 函数指针 ...
- 【最小生成树】BZOJ 1196: [HNOI2006]公路修建问题
1196: [HNOI2006]公路修建问题 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1435 Solved: 810[Submit][Sta ...
- 【BZOJ】【2844】albus就是要第一个出场
高斯消元解XOR方程组 srO ZYF Orz 膜拜ZYF…… http://www.cnblogs.com/zyfzyf/p/4232100.html /******************** ...
- intellij idea 14 ULTIMATE 注册码
Name:happy KEY:63763-YCO0I-QR4TV-G4I3E-4XGK9-GQSQ3
- make -f dc_debug.mak 提示错误"/usr/bin/ld:can not find -l***"解决办法
在公司不同服务器上"make -f ***"程序的时候,有的服务器可以编译通过,有的却提示"/usr/bin/ld:can not find -l***"的错误 ...
- SpringMVC数据绑定全面示例(复杂对象,数组等)
点击链接查询原文 http://www.xdemo.org/springmvc-data-bind/ 已经使用SpringMVC开发了几个项目,平时也有不少朋友问我数据怎么传输,怎么绑定之类的话题,今 ...